递归与分治—— Catalan数C(n)的计算
题意:
Catalan数的定义如下,首先规定C(0)为1,然后按照下式定义C(n)。
例如n=5,C(5)=C(0)C(4)+C(1)C(3)+C(2)C(2)+C(3)C(1)+C(4)C(0)。
前6个Catalan数是1,2,5,14,42,132。要求计算各个Catalan数。
样例输入 | 样例输出 |
---|---|
6 | 132 |
19 | 1 767 263 190 |
35 | 3 116 285 494 907 301 262 |
实验方法1:递归算法。
用递归程序计算C(n),依次输入n=1, 2, 3, …,输出Catalan数,当计算时间大于10秒结束输入,记录能在10秒钟内计算出结果的最大n值,C(n)和计算时间。
完全按照上式设计的递归函数如下:
long long C(int n)
{
if (n == 0)
return 1;
int sum(0);
for (int i = 0; i < n; i++)
sum += C(i) * C(n-1-i);
return sum;
}
完整代码:
#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<ctime>
long long C(int n)
{
int sum=0;
if(n==0){
sum=1;
}
for(int i=0;i<n;i++){
sum+=C(i)*C(n-1-i);
}
return sum;
}
int main()
{
long long int sum,max,m,a,b;
double duration=0,mun;
clock_t start,finish;
start=clock();
for(long long int i=1; ;i++){
max=C(i);
finish=clock();
duration=(double)(finish-start)/CLOCKS_PER_SEC;
if(duration>10){
break;
}
else{
mun=duration;
a=max;
b=i;
}
}
printf("%lld %lld %f\n",b,a,mun);
return 0;
}
实验方法2:非递归算法,按顺序计算C(1), C(2), …, 直至C(n)。
用n=35测试其计算结果和计算时间。
输入:n (n<=35)
输出:C(n),及运行时间
完整代码:
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<ctime>
int main()
{
long long int C[10000];
int n;
clock_t start,finish;
double duration;
start=clock();
C[0]=1;
scanf("%d",&n);
for(int i=1;i<=n;i++){
for(int j=0;j<i;j++){
C[i]+=C[j]*C[i-j-1];
}
}
finish=clock();
duration=(double)(finish-start)/CLOCKS_PER_SEC;
printf("%lld %lf\n",C[n],duration);
return 0;
}