默慈金数
今天,我來講一種比較特殊的數,可能很多人都沒有聽過這種數,它叫默慈金數。但事實是它早就已經進入了ACM競
賽中了。好了,接下來讓我們一起來認識它,并會講述一些它的重要應用。
?
在百度百科上,是這樣定義默慈金數的:一個給定的數的默慈金數是在一個圓上的個點間,畫出彼此不相交弦的
全部方法的總數。比如為4時,方法數為9,如下圖
?
???????????????????
?
默慈金數在幾何,組合數學和數論等領域中皆有其重要用途,它的遞歸定義如下
?
??????
?
接下來是最重要的環節,來探討上述遞推公式的由來。有一篇論文有詳細講解,我已放到豆丁網上,如下
?
鏈接:http://www.docin.com/p1-964777006.html
?
?
其實默慈金數還有很多不同的展現方式,比如:在一個網格上,若限定每步只能向右移動一格,可以右上,右下,
橫向,向右,并禁止移動到以下的地方,則以這種走法移動步從到的可能形成的路徑的總數
為的默慈金數。如下圖示
?
?????
?
接下來,看幾個比較典型的題目。
?
題目:http://acm.hdu.edu.cn/showproblem.php?pid=3723
?
分析:赤裸裸的求默慈金數,用Java處理大數比較方便。實際上默慈金數還有另一個公式,如下
?
???? ?
?
?????對于本題,我們枚舉有步向上,那么必然有步向下,則針對每個得到答案是,求和
???? 后便得到最終答案。
?
代碼:
import java.math.*; import java.util.*;public class Main {public static final int N = 10005;public static final BigInteger MOD = BigInteger.valueOf(10).pow(100);public static BigInteger ans[] = new BigInteger[N];public static void Init(){ans[1] = BigInteger.valueOf(1);ans[2] = BigInteger.valueOf(2);for(int i = 3; i < N; i++){BigInteger a = ans[i - 1].multiply((BigInteger.valueOf(2).multiply(BigInteger.valueOf(i)).add(BigInteger.valueOf(1))));BigInteger b = ans[i - 2].multiply((BigInteger.valueOf(3).multiply(BigInteger.valueOf(i)).subtract(BigInteger.valueOf(3))));ans[i] = (a.add(b)).divide(BigInteger.valueOf(i).add((BigInteger.valueOf(2))));}}public static void main(String[] args){Init();Scanner cin = new Scanner(System.in);while(cin.hasNext()){int n = cin.nextInt();System.out.println(ans[n].mod(MOD));}} }
?
題目:http://acdream.info/problem?pid=1667
?
分析:數一巨巨的題目,仔細想想實際跟上題一樣,直接上默慈金數即可。
?
默慈金數的生成函數詳見:http://mathworld.wolfram.com/MotzkinNumber.html
?
?
講完了默慈金數,還有一類數,叫做那羅延數,具體參考如下鏈接
?
鏈接:http://en.wikipedia.org/wiki/Narayana_number
?
總結
- 上一篇: 自然数幂和取模问题进一步探究
- 下一篇: 浅谈数值稳定性