题目链接: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; }