HDOJ 1023 Train Problem II 卡特兰数

时间:2023-03-08 21:49:26

火车进站出站的问题满足卡特兰数...卡特兰数的相关知识如下:

卡特兰数又称卡塔兰数,是组合数学中一个常出现在各种计数问题中出现的数列。由以比利时的数学家欧仁·查理·卡塔兰 (1814–1894)命名。

前几项为 (OEIS中的数列A000108): 1, 1, 2, 5, 14, 42, 132, 429, 1430, 4862, 16796, 58786, 208012, 742900, 2674440, 9694845, 35357670, 129644790, 477638700, 1767263190, 6564120420, 24466267020, 91482563640, 343059613650, 1289904147324, 4861946401452, ...

令h(1)=1,h(2)=1,catalan数满足递归式:

例如:h(3)=h(1)*h(2)+h(2)*h(1)=1*1+1*1=2

 h(4)=h(1)*h(3)+h(2)*h(2)+h(3)*h(1)=1*2+1*1+2*1=5

h(0)=1;h(1)=1;h(2)=2;h(3)=5;  ····有另类的递归式

另类递归式:

  h(n)=h(n-1)*(4*n-2)/(n+1);

  该递推关系的解为:

h(n)=C(2n,n)/(n+1) (n=1,2,3,...)

可以看出卡特兰数是一个大数据的问题,处理大数据问题一般是将数据的各位存放在一个数组中....

 //h( n ) = ( ( 4*n-2 )/( n+1 )*h( n-1 ) );

 #include<stdio.h>

 //*******************************
//打表卡特兰数
//第 n个 卡特兰数存在a[n]中,a[n][0]表示长度;
//注意数是倒着存的,个位是 a[n][1] 输出时注意倒过来。
//*********************************
int a[][];
void ktl()
{
int i,j,yu,len;
a[][]=;
a[][]=;
a[][]=;
a[][]=;
len=;
for(i=;i<;i++)
{
yu=;
for(j=;j<=len;j++)
{
int t=(a[i-][j])*(*i-)+yu;
yu=t/;
a[i][j]=t%;
}
while(yu)
{
a[i][++len]=yu%;
yu/=;
}
for(j=len;j>=;j--)
{
int t=a[i][j]+yu*;
a[i][j]=t/(i+);
yu = t%(i+);
}
while(!a[i][len])
{
len--;
}
a[i][]=len;
} }
int main()
{
ktl();
int n;
while(scanf("%d",&n)!=EOF)
{
for(int i=a[n][];i>;i--)
{
printf("%d",a[n][i]);
}
puts("");
}
return ;
}