题目:HDU023
N个火车出栈入栈组合数问题,很明显是属于卡特兰数的应用
卡特兰数的前几个数为:
1,2,5,14,42,132,429,1430,4862,16796,58786,208012,742900,2674440,9694845
递推式为:h( n ) = ( ( 4*n-2 )/( n+1 )*h( n-1 ) ) (n>=2)
当然它还有其他的递推式,看一下这位大佬的就知道了:传送门
好吧,先来看一下当n=100时,是多大的一个数吧:
896519947090131496687170070074100632420837521538745909320
没错,就是这么长,那么即使我们使用long long 也是不够用的,所以我们需要使用大数运算。
那么就来看一下具体的代码实现吧:
#include<bits/stdc++.h>
using namespace std;
int a[110][110];
void cantalan()
{
memset(a,0,sizeof(a)); //初始化
a[1][0]=1; //a[i][0]表示第 i 个数的位数
a[1][1]=1;
a[2][0]=1;
a[2][1]=2;
int len=1;
for(int i=3; i<=100; i++)
{
int yu=0;
for(int j=1; j<=len; j++)
{
a[i][j]=a[i-1][j]*(4*i-2)+yu;
yu=a[i][j]/10; // yu 表示进位
a[i][j]%=10;
}
while(yu)
{
a[i][++len]=yu%10;
yu/=10;
}
for(int j=len; j>=1; j--) //模拟除法
{
int t=a[i][j]+yu*10;
a[i][j]=t/(i+1);
yu=t%(i+1);
}
while(!a[i][len]) //消除前导0
len--;
a[i][0]=len;
}
}
int main()
{
cantalan();
int n;
while(cin>>n)
{
for(int i=a[n][0]; i>0; i--) //由于存的时候时逆着存的,输出也应该从后往前
cout<<a[n][i];
cout<<endl;
}
return 0;
}