>Description
【题目背景】
共2N人在圆周上作战(不在圆的内部)。
其中的N个人每个人会前往另一个人那里结伴作战,在途中同学们只会走两点所连的直线。但是一旦发现地面上有一条脚印横在眼前的时候,同学们就不会通过。你计算一下到底有多少种方案,使得所有的人都能去持续作战。
下图的方案是不可行的:
【问题描述】
给出N,请你求出方案总数。
>Input
一行一个整数N。
>Output
一行一个整数,为方案总数。
无解输出“No Solution”,注意大小写及之间的一个空格,不包括引号。
因为方案数可能很大,所以你懂的…
>Sample Input
5
>Sample Output
42
【数据范围】
对于30%数据: n<=30。
对于100%数据: n<=100。
>解题思路
这一道题就是一道卡特兰数的题(不会的可以去查一下)
由于数太大,所以要用高精。
>代码
#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;
const int maxn=100;
int n,f[105][maxn],c[maxn];
void lil(int a,int b,int s)
{
memset(c,0,sizeof(c));
for(int i=1;i<maxn;i++)
for(int j=1;j<maxn;j++)
{
c[i+j-1]+=f[a][i]*f[b][j];
c[i+j]+=c[i+j-1]/10;
c[i+j-1]%=10; //高精乘高精
}
for(int i=1;i<maxn;i++)
{
f[s][i]+=c[i];
f[s][i+1]+=f[s][i]/10;
f[s][i]%=10; //处理进位
}
}
void output()
{
int i=maxn-1;
while(f[n][i]==0) i--;
for(int j=i;j>=1;j--)
printf("%d",f[n][j]);
} //输出
int main()
{
// freopen("war.in","r",stdin);
// freopen("war.out","w",stdout);
scanf("%d",&n);
f[0][1]=1;
f[1][1]=1; //初值
for(int i=2;i<=n;i++)
for(int j=0;j<i;j++)
lil(j,i-j-1,i); //卡特兰数
output();
return 0;
}