卡特兰数 应用
卡特兰数真是一个神奇的数字,很多组合问题的数量都和它有关系,例如:
- Cn= 长度为 2n的 Dyck words的数量。 Dyck words是由 n个 X和 n个 Y组成的字符串,并且从左往右数, Y的数量不超过 X,例如长度为 6的 Dyck words为:
XXXYYY XYXXYY XYXYXY XXYYXY XXYXYY
- Cn= n对括号正确匹配组成的字符串数,例如 3对括号能够组成:
((())) ()(()) ()()() (())() (()())
- Cn= n+1个数相乘,所有的括号方案数。例如, 4个数相乘的括号方案为:
((ab)c)d (a(bc))d (ab)(cd) a((bc)d) a(b(cd))
- Cn= 拥有 n+1 个叶子节点的二叉树的数量。例如 4个叶子节点的所有二叉树形态:
- Cn=n*n的方格地图中,从一个角到另外一个角,不跨越对角线的路径数,例如, 4×4方格地图中的路径有:
- Cn= n+2条边的多边形,能被分割成三角形的方案数,例如 6边型的分割方案有:
- Cn= 圆桌周围有 2n个人,他们两两握手,但没有交叉的方案数。
引用:http://blog.163.com/kevinlee_2010/blog/static/169820820201010894212352/
求一个数的卡塔兰数
使用递推式 H(n) = c(2n,n)/n+1;
改写为A(2n,n)/ (n+1)!
使用大数相乘相除计算
#include <cstdio>
#include <iostream>
#include <cstring>
using namespace std;
#define N 250
int a[N];
void init(int n)
{
memset(a,0,sizeof(a));
a[0] = 1;
int i = 0;
int j = 0;
int k1 = 1;
for(i = 2*n; k1 <= n; i--,k1++)
{
int t = 0;
int mul = 0;
for(j = 0; j <= N; j++)
{
mul = a[j] *i + t;
a[j] = mul % 10;
t = mul / 10;
}
}
for(i = 2; i <= n+1; i++)
{
int t1 = 0;
int mul1 = 0;
for(j = N; j >= 0;j--)
{
mul1 = mul1 *10 + a[j];
a[j] = mul1 / i;
mul1 %= i;
}
}
int k = N;
while(k--)
if(a[k])
break;
k += 1;
while(k--)
printf("%d",a[k]);
printf("\n");
}
int main()
{
int n;
while(scanf("%d",&n) != EOF)
{
if(n < 2)
printf("%d\n",1);
else
init(n);
}
return 0;
}