WZK打雪仗
题目大意
- 就是在一个环上有2n个点,问有多少种连法可以用n条线连接成n对点.
输入样例
5
输出样例
42
数据范围
- 【数据范围】
对于30%数据: n<=30。
对于100%数据: n<=100。
解题思路
- 其实这道题要看规律,你会发现其实就是卡特兰数,就可以得出公式:
f[n]=∑i=0n−1f[i]∗f[n−i−1]f[n]=\sum_{i=0}^{n-1} f[i]*f[n-i-1]f[n]=i=0∑n−1f[i]∗f[n−i−1]
程序如下
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#define lon 1000000000
using namespace std;
long long n,a[1001][1001],f[1001],t;
void gjc(int x,int y)
{
for(int i=1;i<=100;++i)
{
for(int j=1;j<=100;++j)
{
f[i+j-1]+=a[x][i]*a[y][j];
f[i+j]+=f[i+j-1]/lon;
f[i+j-1]%=lon;
}
}
}
void gjj(int x)
{
for(int i=1;i<=100;++i)
{
a[x][i]+=f[i];
a[x][i+1]+=a[x][i]/lon;
a[x][i]%=lon;
f[i]=0;
}
}
int main()
{
freopen("war.in","r",stdin);
freopen("war.out","w",stdout);
scanf("%lld",&n);
a[0][1]=1;
a[1][1]=1;
for(int i=2;i<=n;++i)
{
for(int j=0;j<i;++j)
{
gjc(j,i-j-1);
gjj(i);
}
}
t=10;
while(!a[n][t]&&t>0) t--;
printf("%lld",a[n][t]);
for(int i=t-1;i>0;--i)
printf("%0*lld",9,a[n][i]);
return 0;
}