一、原题
3.笨笨连线游戏(route.cpp)
【题目描述】
一天,妈妈在黑板上画了一个大大的圆,然后又在圆弧上标上1,2,3,...,,2N个数。然后让笨笨任意选取一对数(两个不同的数)上连一条直线。然后再任意选取一对数,再边一条直线,但这条直线不能和任何别的直线相交。每个数都要恰好与另一个数连一条直线。
笨笨费了好大的劲才找出一种连线方案。妈妈在旁边问笨笨:给出N,请问不同的连线方案有多少种呢?
笨笨算不出来,只好请教作为大牛的你。
【输入】
多组数据,每组数据的格式为:
第1行:1个整数N(1<= N <= 150),表示在圆弧上会标记2N个数
当输入的N为0时,表示输入结束。
【输出】
每组输入对应输出一行,一个整数,表示连线的方案数。由于结果太大,只保留模10007后的余数。
【样例输入】
2
3
0
【样例输出】
2
5
二、分析
这道题要用到递推来做,思路类似“Catalan数”,前往百度:Catalan数
- 当n=0时,f(0)=1;
- 当n=1时,f(1)=1;
- 当n=2时,f(2)=f(0)*f(1)+f(1)*f(0)=2;
-
当n=3时,f(3)=f(1-1)*f(3-1)+f(1)*f(3-2)+f(2)*f(3-3);
-
f(n)=f(0)*f(n-1)+f(1)*f(n-2)+...+ f(n-1)*f(0)
第2当n=2时,从1号点出发划一条直线的方案是f(1-1)*f(2-1),从2号点出发划一条直线的方案是f(2-1)*f(2-2),总方案是从1号和2号点出发方案之和。
三、源代码
#include<cstdio>
int f[151],n,j,k,i;
int main()
{
freopen("route.in","r",stdin);
freopen("route.out","w",stdout);//文件的读入输出
f[0]=1;f[1]=1;f[2]=2;
for(i=3;i<=150;i++)//计算出150以内的所有解
{
for(j=0,k=i-1;j<i;j++,k--)
f[i]+=f[j]*f[k]%10007;
f[i]=f[i]%10007;
}
while(scanf("%d",&n)==1)//输入n
{
if(n==0)//如果n是0,结束程序
return 0;
printf("%d\n",f[n]);//如果不是,输出结果
}
}