卡特蘭數列(Catalan )
阿新 • • 發佈:2019-01-31
簡述
卡特蘭數又稱卡塔蘭數,它是組合數學中一個常出現在各種計數問題中出現的數列,其前幾項為 : 1, 1, 2, 5, 14, 42, 132, 429, 1430, 4862, 16796, 58786, 208012, ......
公式
1.遞迴公式1
2.遞迴公式2
3.組合公式1
4.組合公式 2
5.增長趨勢
應用
- 二叉樹的計數:已知二叉樹有 n 個結點,求能構成多少種不同的二叉樹
- 括號化問題:一個合法的表示式由()包圍,()可以巢狀和連線,如:(())()也是合法表示式,現給出 n 對括號,求可以組成的合法表示式的個數
- 劃分問題:將一個凸 n+2 多邊形區域分成三角形區域的方法數
- 出棧問題:一個棧的進棧序列為1,2,3,..n,求不同的出棧序列有多少種
- 路徑問題:在 n*n 的方格地圖中,從一個角到另外一個角,求不跨越對角線的路徑數有多少種
- 握手問題:2n 個人均勻坐在一個圓桌邊上,某個時刻所有人同時與另一個人握手,要求手之間不能交叉,求共有多少種握手方法
This is the code
#include<iostream> #include<cstring> #include<cstdio> using namespace std; long long cat[50]; long long Cat1(int n) { memset(cat,0,sizeof(cat)); cat[0]=cat[1]=1; for(int i=2;i<=n;++i) { for(int j=0;j<i;++j) cat[i]+=cat[j]*cat[i-j-1]; } return cat[n]; } int main() { int n; scanf("%d",&n); printf("%lld\n",Cat1(n)); return 0; }
#include<iostream> #include<cstring> #include<cstdio> using namespace std; long long cat[50]; long long Cat2(int n) { memset(cat,0,sizeof(cat)); cat[0]=1; for(int i=1;i<=n;++i) { cat[i]=((cat[i-1])*(i*4-2))/(i+1); } return cat[n]; } int main() { int n; scanf("%d",&n); printf("%lld\n",Cat2(n)); return 0; }
#include<iostream>
#include<cstring>
#include<cstdio>
using namespace std;
long long cat[50];
long long tatal;
void Cat3(int n)
{
tatal=1;
for(int i=0;i<n;++i)//求c(2n,n);
tatal=tatal*(2*n-i)/(i+1);
tatal/=(n+1);
}
int main()
{
int n;
scanf("%d",&n);
Cat3(n);
printf("%lld\n",tatal);
return 0;
}
兩個公式相當於一個,第一個是用第二個化簡來的
#include<iostream>
#include<cstring>
#include<cstdio>
using namespace std;
long long cat[50];
long long tatal;
void Cat4(int n)
{
tatal=1;
for(int i=0;i<n;++i)//求c(2n,n);
tatal=tatal*(2*n-i)/(i+1);
tatal=tatal-tatal*n/(n+1);
}
int main()
{
int n;
scanf("%d",&n);
Cat4(n);
printf("%lld\n",tatal);
return 0;
}