catalan数(poj1095)

  这题个人感觉算是递归的经典吧!

  这里给出一个这题的解题报告链接,个人感觉已经写得很好了。

http://blog.csdn.net/lvlu911/archive/2010/03/28/5425974.aspx

提示大家要注意的几点是要紧紧抓住递归方程的定义,这句:

递归函数fun(n,k)。即打印出拥有n个结点树的第k种状态。

可能大家对这句话不是怎么理解:

  对于s,该树的左子树编号为(s-1)/L[n-i-1]+1,右子树编号为(s-1)% L[n-i-1]+1

  我个人的理解是把状态数s先看成L[n-i-1]进制的数s-1(从0开始计数),则:

左子树对应的数应该是(s-1)/L[n-i-1],右子树对应的数应该是(s-1)%L[n-i-1]。

然后再转成我们需要的状态数(s-1)/L[n-i-1]+1,(s-1)% L[n-i-1]+1,即

状态->数->状态

  最后晒上自己的代码,方便以后复习,呵呵……

#include<iostream> using namespace std; #define N 50 unsigned int c[N]; int Max,index; void catalan(){ c[0]=c[1]=1; index=1; Max=1; while(Max<500000000){ index++; c[index]=c[index-1]*(4*index-2)/(index+1); Max=Max+c[index]; } } void preOder(int n,int k){//n¸ö½áµãµÄµÚkÖÖ if(n==1){ cout<<'X'; return; } int i; int s=0; for(i=0;i<n;i++){ s+=c[i]*c[n-i-1]; if(s>=k){ s-=c[i]*c[n-i-1]; break; } } k-=s;//×ó×ÓÊ÷Ϊi£¬ÓÒ×ÓÊ÷Ϊn-i-1¸ö½áµãµÄµÚkÖÖ if(i){ cout<<"("; preOder(i,(k-1)/c[n-i-1]+1); cout<<')'; } cout<<'X'; if(n-i-1){ cout<<'('; preOder(n-i-1,(k-1)%c[n-i-1]+1); cout<<')'; } } int main(){ catalan(); int num; while(cin>>num&&num){ int i,sum=0; for(i=1;num>sum;i++)sum+=c[i]; i--;//Í˳öʱ»á×Ô¼ÓÒ» preOder(i,num+c[i]-sum); cout<<endl; } return 0; }

你可能感兴趣的:(catalan数(poj1095))