您的位置:首页 > 其它

HDU 3723 Delta Wave(2010 Asia Tianjin Regional Contest )

2015-10-03 20:51 423 查看
【题目链接】http://acm.hdu.edu.cn/showproblem.php?pid=3723

【解题报告】

结论题,知道是卡特兰数的话就会很好写。

我们知道最后偏移量为0,所以假如向上偏移一次,就一定会有对应的向下偏移一次。这类似一个入栈出栈操作。

假如有i次入栈,那么对应的i个数的出栈序列为:

2*C(  2i,n )*Cat(i).


其中:

cat(i)=cat(i-1)*2(2i-1)/(i+1);


化简公式得到递推式为:

ans[i]/ans[i-1]=(n-2i+2)*(n-2i+1)/(i*(i-1));


然后高精度递推计算,累加ans[i]即可。

【参考代码】

#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;

const int maxn=100000;

int C[maxn],ans[maxn];
int n,len;

int main()
{
while( ~scanf("%d",&n) )
{
memset(C,0,sizeof(C));
memset(ans,0,sizeof(ans));
C[1]=1; len=1;  //i=0的时候
ans[1]=1;  //i=0的时候
for( int i=1; i*2<=n; i++ )
{
for( int j=1; j<=len; j++ ) C[j]*=(n-2*i+2)*(n-2*i+1);
for( int j=1; j<len; j++ ) if(C[j]>9){ C[j+1]+=C[j]/10; C[j]%=10; }
while( C[len]>10 )//进位
{
C[len+1]=C[len]/10;
C[len]%=10;
len++;
}
for( int j=len; j>=1; j-- )
{
if( C[j]/(i*(i+1))==0 )
{
C[j-1]+=C[j]*10;
C[j]=0;
if(len==j)len--;
}
else
{
C[j-1]+=C[j]%(i*(i+1))*10;
C[j]/=i*(i+1);
}
}
for( int j=1; j<=100; j++ )ans[j]+=C[j];
for( int j=1; j<=100; j++ )
{
if( ans[j]>9 )
{
ans[j+1]+=ans[j]/10;
ans[j]%=10;
}
}
}
int ans_len=100;
while( ans[ans_len]==0 )ans_len--;
for( int i=ans_len; i>=1; i-- )printf("%d",ans[i]);
printf("\n");
}

return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: