題意:將1~2n個數按照順時針排列好,用一條線將兩個數字連接起來要求:線之間不能有交點,同一個點只允許被連一次。
最后問給出一個n,有多少種方式滿足條件。
卡特蘭數(列):
令h(0)=1,h(1)=1,catalan數滿足遞推式:h(n)= h(0)*h(n-1)+h(1)*h(n-2) + ... + h(n-1)h(0) (n>=2)
例如:h(2)=h(0)*h(1)+h(1)*h(0)=1*1+1*1=2???????????? ? h(3)=h(0)*h(2)+h(1)*h(1)+h(2)*h(0)=1*2+1*1+2*1=5
另類遞推式:??????? h(n)=h(n-1)*(4*n-2)/(n+1);
遞推關系的解為: h(n)=C(2n,n)/(n+1) (n=0,1,2,...)
遞推關系的另類解為:??? h(n)=c(2n,n)-c(2n,n-1)(n=0,1,2,...)
一些方面的應用:
1. 括號化:矩陣連乘:P=a1×a2×a3×……×an,依據乘法結合律,不改變其順序,只用括號表示成對的乘積,試問有幾種括號化的方案?(h(n-1)種)
2.一個棧(無窮大)的進棧序列為1,2,3,…,n,有多少個不同的出棧序列?
3.給定n個點求能組成的二叉樹所有總數。
4. 凸多邊形三角劃分(任意兩頂點之間的連線必能相交),求有多少中分割的方法(類似:在圓上選擇2n個點,將這些點成對連接起來使得所得到的n條線段不相交的方法數)?
5. n層階梯切割為n個矩形的切割方法總數
代碼
#include<bits/stdc++.h> using namespace std; typedef long long ll; const int maxn = 1000000; const int moder = 1000000; int a[105][100]; void catalan() //求卡特蘭數,a[i][j]存儲的是第i個逆序(高位在后)的卡特蘭數(從0開始),且未對高位0進行處理 {int i, j, len, carry, temp;a[1][0] = 1;len = 1;for(i = 2; i <= 100; i++){for(j = 0; j < len; j++) //乘法a[i][j] = a[i-1][j]*(4*(i-1)+2);carry = 0;for(j = 0; j < len; j++) //處理相乘結果 {temp = a[i][j] + carry;a[i][j] = temp % 10;carry = temp / 10;}while(carry) //進位處理 {a[i][len++] = carry % 10;carry /= 10;}carry = 0;for(j = len-1; j >= 0; j--) //除法 {temp = carry*10 + a[i][j];a[i][j] = temp/(i+1);carry = temp%(i+1);}} } int main() {int n;catalan() ;while(scanf("%d",&n) ,n != -1){int flag = 0 ;for(int i = 99;i >= 0;i--)//處理高位 {if(a[n][i] != 0)flag = 1;if(flag)printf("%d",a[n][i]);}printf("\n");}return 0; }
————不是很懂