poj2084
几经波折
虽然写出了递归式,但是一提交,超时。然后改成了不用递归,先算出所有值,存到数组里,结果WA。然后发现,n=100时数太大太大,要用大数来处理。不想写大数的程序,所以改用java写,终于AC
C++的两个版本:

1 #include <stdio.h> 2 #include <string.h> 3 int connection[201]; 4 int connect(int m,int n) 5 { 6 if(n==m+1) 7 return 1; 8 if(m>=n) 9 return 1; 10 //n>m+1 11 int i; 12 int count=0,mid,t1,t2; 13 for(i=0;(mid=m+2*i+1)<=n;i++) 14 { 15 //m connect to m+2*i+1 16 t1=connect(m+1,m+2*i); 17 t2=connect(m+2*i+2,n); 18 count+=(t1*t2); 19 } 20 return count; 21 } 22 int init_dp() 23 { 24 int n,i; 25 memset(connection,0,sizeof(connection)); 26 connection[0]=1; 27 connection[2]=1; 28 for(n=4;n<=200;n+=2) 29 for(i=0;i<n;i+=2) 30 { 31 connection[n]+=connection[i]*connection[n-2-i]; 32 } 33 } 34 35 int main() 36 { 37 int n; 38 init_dp(); 39 while(1) 40 { 41 scanf("%d",&n); 42 if(n==-1) 43 return 0; 44 printf("%d\n",connect(1,2*n)); 45 printf("%d\n",connection[2*n]); 46 } 47 }
java的版本:

1 import java.math.*; 2 import java.util.*; 3 import java.io.*; 4 5 public class Main{ 6 7 /** 8 * @param args 9 */ 10 public static void main(String[] args) { 11 // TODO Auto-generated method stub 12 BigInteger[] h=new BigInteger[201]; 13 h[0]=new BigInteger("1"); 14 h[2]=new BigInteger("1"); 15 int n,i; 16 for(n=4;n<=200;n+=2) 17 { 18 h[n]=new BigInteger("0"); 19 for(i=0;i<n;i+=2) 20 { 21 h[n]=h[n].add(h[i].multiply(h[n-2-i])); 22 } 23 } 24 Scanner cin =new Scanner(new BufferedInputStream(System.in)); 25 while(true){ 26 n=cin.nextInt(); 27 if(n==-1) 28 break; 29 System.out.println(h[2*n]); 30 } 31 } 32 33 }
另有解说:
分析:catalan数
令h(1)=1,h(0)=1,catalan数满足
递归式: h(n)= h(0)*h(n-1)+h(1)*h(n-2) + ... + h(n-1)h(0) (其中n>=2)
另类递归式: h(n)=((4*n-2)/(n+1))*h(n-1);
该递推关系的解为: h(n)=C(2n,n)/(n+1) (n=1,2,3,...)
它的适用情况有:
1、取物2n个,物品分a,b两种,任意时刻手中的a物品数<b物品数,的方法数为h(n)。
2、把(n+2)边形分割成若干个三角形组面积组合的方法数为h(n)。
3、一圆环上有2n个点两两连线不交叉的方法数为h(n)。
递归式和我的差不多,不过另类递归式就不知怎么出来的了。