题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1023
题目大意:序号为1~N的车厢按栈的方式随意进出站,问共有多少种出站结果。
关键思想:卡特兰数。高精度(因为递推式中有分数)。
卡特兰数解决的问题:任意两种操作,要求每种操作的总次数一样,
且进行第k次操作2前必须先进行至少k次操作1
代码如下:
/*————————————
@卡特兰数大数模板
【a[n][0]存放长度len,a[i]为第i个Catelan数 ! 】
(1)卡特兰数解决的问题:任意两种操作,要求每种操作的总次数一样,
且进行第k次操作2前必须先进行至少k次操作1
(2)递推式:h(n)=((4*n-2)/(n+1))*h(n-1)
(3)通项:C(n,2n)/(n+1)或者C(n,2n)-C(n-1,2n)
————————————————*/
#include <iostream>
#include <cmath>
using namespace std;
const int MAXN=105;
int a[MAXN][MAXN];
//
void Catalan(){
int mu,len=1; //mu在乘法中是乘的结果,除法中是除法的结果
a[1][0]=1,a[1][1]=1;
for(int i=2;i<MAXN;i++){
for(int j=1;j<=len;j++){
int t=a[i-1][j]*(4*i-2)+mu; //每位*(4i-2)+低位进上来的结果
mu=t/10; //上述结果/10为进给高位的
a[i][j]=t%10; //上述结果%10为当前位的结果。
}
while(mu){ //最高位多出的位数
a[i][++len]=mu%10;
mu/=10;
}
for(int j=len;j>=1;j--){
int t=a[i][j]+mu*10; //当前位+高位借下来的结果
a[i][j]=t/(i+1); //上述结果/(i+1)为当前位的结果
mu=t%(i+1); //上述结果%(i+1)为要借给低位的
}
while(!a[i][len]) len--; //长度要减去高位的0
a[i][0]=len;
}
}
int main(){
int n;
Catalan();
while(cin>>n){
for(int i=a[n][0];i>0;i--)
cout<<a[n][i];
cout<<endl;
}
return 0;
}