题目
时间限制: 1 Sec 内存限制: 128 MB
题目描述
Czyzoiers 都想知道小 x 为什么对鸡蛋饼情有独钟。经过一番逼问,小 x 道出了实情:因为他喜欢圆。
最近小 x 又发现了一个关于圆的有趣的问题:在圆上有2N 个不同的点,小 x 想用 N 条线段把这些点连接起来(每个点只能连一条线段),使所有的线段都不想交,他想知道这样的连接方案有多少种?
输入
有且仅有一个正整数 N(N≤3000)。
输出
要求的方案数(结果 mod 100000007)。
样例输入
2
样例输出
2
提示
1 号点与 2 号点连接:2 种。
1 号点与 4 号点连接:1 种。
1 号点与 6 号点连接:2 种。
题意
就是说,给一个数n,一个圆上有2*n个点,然后问有几种方法可以用n条不相交的线段把这2*n个点连接起来。
思路
分治 加 动态规划,枚举从第一个点开始找第偶数个点,连成一条线段,之后这条线段两边有偶数个点(计为x,y),把这x,y各看作是两个圆上的点,即当n=x/2时和n=y/2时的情况,加一个数组记忆化,实现DP。
代码实现如下。
//Time:12 ms
//Memory:1808 kb
#include <iostream>
#include <stdio.h>
#include <algorithm>
#include <cstring>
using namespace std;
int main()
{
#ifndef ONLINE_JUDGE
freopen("1.txt","r",stdin);
#endif // ONLINE_JUDGE
long long int n,a[30005];
memset(a,0,sizeof(a));
a[0]=1;
a[1]=1;
a[2]=2;
a[3]=5;
cin>>n;
for(int i=4;i<=n;++i)
{
int x=2*i;
int y,z;
for(int j=2;j<=x;j+=2)
{
y=(j-2)/2;
z=(x-j)/2;
a[i]+=a[y]*a[z];
a[i]%=100000007;
}
}
cout<<a[n]<<endl;
return 0;
}