原部落格:
卡特蘭數:
1 通項公式:h(n)=c(n,2n)/(n+1)=(2n)!/((n!)*(n+1)!)
2遞推公式:h(n)=((4
*n-2
)/(n+
1))*h(n-1
);h(n)=h(0)*h(n-1)+h(1)*h(n-2)+...+h(n-1)*h(0).
h(n)=c(n,2n)-c(n+1,2n);
3前幾項為:h(0)=1,h(1)=1,h(2)=2,h(3)=5,h(4)=14,h(5)=42,......
4應用場景:
a.括號化問題
矩陣鏈乘: p
=a1×a2×a3×……×an,依據乘法結合律,不改變其順序,只用括號表示成對的乘積,試問有幾種括號化的方案?(h(n)種)
b.出棧次序問題
乙個棧(無窮大)的進棧序列為1,2,
3,..n,有多少個不同的出棧序列
?類似:(1
)有2n個人排成一行進入劇場。入場費5元。其中只有n個人有一張5元鈔票,另外n人只有10元鈔票,劇院無其它鈔票,問有多少中方法使得只要有10元的人
買 票,售票處就有5元的鈔票找零?(將持5元者到達視作將5元入棧,持10元者到達視作使棧中某5元出棧)(2
)在圓上選擇2n個點,將這些點成對連線起來,使得所得到的n條線段不相交的方法數。
c.將多邊行劃分為三角形問題
(1)將乙個凸多邊形區域分成三角形區域的方法數
(2)類似:一位大城市的律師在她住所以北n個街區和以東n個街區處工作。每天她走2n個街區去上班。如果她從不穿越(但可以碰到)從家到辦公室的對角線,那 麼有多少條可能的道路?
(3)類似:在圓上選擇2n個點,將這些點成對連線起來使得所得到的n條線段不相交的方法數
d.給頂節點組成二叉樹的問題。
給定n個節點,能構成多少種形狀不同的二叉樹
(一定是二叉樹
!先去乙個點作為頂點,然後左邊依次可以取0至n
-1個相對應的,右邊是n
-1到0個,兩兩配對相乘,就是h(0
)*h(n-1)
+h(2)
*h(n-2
)++h(n-1
)h(0)=
h(n))(能構成h(n)個)。
下面給出hdu上面的有關例題:
hdoj 1134
2n個人圍成乙個圓圈,求兩兩相互握手並且不交叉的所有握手方式。
這個是卡特蘭數的乙個例子,設2n個人一共有h(n)種,那麼現在第乙個人可以和第2,4,6,。。。,2(n-1),2n,即必須保證和他握手的那個人兩邊是偶數,即為:
h(n)=h(0)*h(n-1)+h(1)*h(n-2)+...+h(n-1)*h0=(4*n-2)/(n+1) *h(n-1),h(0)=1,h(1)=1.
通項公式:h(n)=c(n,2n)/n+1=(2n)!/((n!)*(n+1)!)
但是這個題目是大數,所以必須採用陣列模擬乘除法.
源**:
#include #include using namespace std;
const int n=105;
int catalan[102][n];
void setcatalan()
}for(j=0;j=0;--j)
for(j=0;j>n && (-1 != n))}}
//*(m-n+1)
int k=m-n+1;
for(j=0;j=base)
}// /(m+1)
int yushu=0;
k=m+1;
for(j=max-1;j>=0;--j)
printf("test #%d:\n",++cas);
j=max-1;
while(!tmp[j])
--j;
// cout<
printf("%03d",tmp[j]);
printf("\n");}}
return 0;
}
卡特蘭數,高精度卡特蘭數
簡單介紹 卡特蘭數是組合數學中常常出現的乙個數列。個人認為不管是遞推公式還是代表的含義都比斐波那契數列難理解一些。遞推公式 應用 1.cn表示長度2n的dyck word的個數。dyck word是乙個有n個x和n個y組成的字串。且全部的字首字串皆滿足x的個數大於等於y的個數。下面為長度為6的dyc...
卡特蘭數和超級卡特蘭數
這篇部落格主要是想講一下超級卡特蘭數 大施洛德數 順帶就想講一下卡特蘭數.卡特蘭數記為 c n c 1 1 forall n geq 2,c n sum c i c 前幾項大概是 1,1,2,5,14,42,132.直接遞推未免效率太低,我們考慮用生成函式優化.顯然有 c x c x 2 x 解得 ...
卡特蘭數 Catalan
問題 程式設計之美 第4.3節中提到了 買票找零 問題,查閱了下資料,此問題和卡特蘭數 cn有關,其定義如下 卡特蘭數真是乙個神奇的數字,很多組合問題的數量都和它有關係,例如 yyy xyxxyy xyxyxy xxyyxy xxyxyy ab c d a bc d ab cd a bc d a b...