HDU 1023 [Train Problem II]Catelan数

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

  

 

posted @ 2017-02-16 23:23  哇咔咔咔  阅读(407)  评论(0编辑  收藏  举报