HDOJ 1023 Train Problem II(卡特兰数+大数乘除法)
发布时间:2021-05-27 09:35:51 所属栏目:大数据 来源:网络整理
导读:Train Problem II Time Limit: 2000/1000 MS (Java/Others)????Memory Limit: 65536/32768 K (Java/Others) Total Submission(s): 7690????Accepted Submission(s): 4140 Problem Description As we all know the Train Problem I,the boss of the Ignatiu
|
Train Problem IITime Limit: 2000/1000 MS (Java/Others)????Memory Limit: 65536/32768 K (Java/Others) Total Submission(s): 7690????Accepted Submission(s): 4140Problem Description As we all know the Train Problem I,the boss of the Ignatius Train Station want to know if all the trains come in strict-increasing order,how many orders that all the trains can get out of the railway. ? Input The input contains several test cases. Each test cases consists of a number N(1<=N<=100). The input is terminated by the end of file. ? Output For each test case,you should output how many ways that all the trains can get out of the railway. ? Sample Input 1 2 3 10? Sample Output
1 2 5 16796
Hint
The result will be very large,so you may not process it by 32-bit integers.
?
题意:n辆火车编号为1~n,按照编号递增的顺序进入火车站(栈模型),出站的情况有多少种? 题解:我们可以把题目看成这样的模型:一个栈(无穷大)的进栈序列为1,2,3,…,n,有多少个不同的出栈序列? ?? 首先,我们设f(n)=序列个数为n的出栈序列种数。同时,我们假定第一个出栈的序数是k。 第一个出栈的序数k将1~n的序列分成两个序列,其中一个是1~k-1,序列个数为k-1,另外一 个是k+1~n,序列个数是n-k。 此时,我们若把k视为确定一个序数,那么根据乘法原理,f(n)的问题就等价于——序列个数为k-1的出栈序列种数乘以序列个数为n - k的出栈序列种数,即选择k这个序数的f(n)=f(k-1)×f(n-k)。 而k可以选1到n,所以再根据加法原理,将k取不同值的序列种数相加,得到的总序列种数为: f(n)= f(0)f(n-1) +f(1)f(n-2)+……+f(n-1)f(0)。 那么这个式子到底有什么作用,怎么求和呢? 这个式子就是组合数学中的卡特兰数的递推式。卡特兰数的递推式形态一共有如下几种: 令h(0)=1,h(1)=1,catalan数满足递推式[1] : 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 另类递推式[2] ?: 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,...) ? 有关卡特兰数的几篇博文Y(^o^)Y:?博文1? ??博文2? ?博文3? ? 代码就用了kuangbin大牛的板子,很好懂,如下: //h(n)=h(n-1)*(4*n-2)/(n+1);
#include<cstdio>
#include<cstring>
using namespace std;
int a[110][110];
//a[n][0]表示n的卡特兰数的长度,存储是反向的,a[n][1]表示个位数
void ktl()//打表
{
int i,j,len;
int c,s;
a[1][0]=1;
a[1][1]=1;
a[2][0]=1;
a[2][1]=2;
len=1;
for(i=3;i<101;++i)
{
c=0;
for(j=1;j<=len;++j)
{
s=a[i-1][j]*(4*i-2)+c;
c=s/10;
a[i][j]=s%10;
}
while(c)
{
a[i][++len]=c%10;
c/=10;
}
for(j=len;j>0;--j)
{
s=a[i][j]+c*10;
a[i][j]=s/(i+1);
c=s%(i+1);
}
while(!a[i][len])
len--;
a[i][0]=len;
}
}
int main()
{
ktl();
int n;
while(scanf("%d",&n)!=EOF)
{
for(int i=a[n][0];i>0;--i)
printf("%d",a[n][i]);
printf("n");
}
return 0;
}
(编辑:新余站长网) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |
站长推荐


