• zoj 2711 Regular Words DP,“高维的” 卡特兰数 (8-H)


    题目地址:http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemCode=2711

    题解:1记录num[i][j][k]   表示从第一个字符开始,长度为i+j+k的,A的个数为i,B的个数为j,C的个数为k的字符串的个数。  

    则如果i>=j>=k  则可以根据最后一个字符是A, B还是C,分三类计数,假设是最后一位是A,由于题目的要求是前缀 ,所以前面的放法数恰好是num[i-1][j-1][k]

    另外两种情况同理,加的时候注意下标小于零就不要了

                 2一开始把所有的元素赋值为0,这样在三重for 中,根本没有将不满足ijk 不等关系的量作为左值。  

                 3之所以可以这么算,是因为计算到i,j,k时需要的数据一定在之前算过了~


                  (这里只是把这个三维矩阵求了一个转置,不影响最后的结果num[n][n][[n])  

    import java.math.*;
    import java.util.*;
    import java.io.*;
    public class Main {
    	  
    	
    
    
    	    public static void main(String[] args) throws Exception {
    		
    	    	 
    	        BigInteger [][][] num=new BigInteger [65][65][65];
    	        
    	         for(int i=0;i<65;i++)
    	        	 for(int j=0;j<65;j++)
    	        		 for(int k=0;k<65;k++)
    	        			    num[i][j][k]=BigInteger.ZERO;
    	         
    	        num[0][0][0]=BigInteger.ONE;
    	         for(int i=0;i<65;i++)
    	        	 for(int j=i;j<65;j++)
    	        		 for(int k=j;k<65;k++)
    	        		    
    	        			 {
    	        			   if(i>0)num[i][j][k]= num[i][j][k].add(num[i-1][j][k]);
    	        			   if(j>0)num[i][j][k]= num[i][j][k].add(num[i][j-1][k]);
    	        			   if(k>0)num[i][j][k]= num[i][j][k].add(num[i][j][k-1]);
    	        			 }
    	             
    	         
    	           Scanner cin=new Scanner(System.in);
    	             while(cin.hasNext())
    	             {  
    	            	 int n=cin.nextInt();
    	                 System.out.println(num[n][n][n]);
    	                 System.out.println();
    	             }
    		      
    	    }
    	  
    	   
    	    
    }


    联想到括号匹配问题,长度为2n的字符串,有n个 “(” , 有n个“)” ,那么合法的式子(可以满足括号匹配)一共有多少?    答案就是 c(2n,n)-c(2n,n-1)=c(2n,n)/(n+1) =h(n)就是卡特兰数 ,也可以按照本题的思想来求   (当然要用高精度,下面写的到最后就溢出了)


    #include<iostream>
    using namespace std;
    typedef long long inta;
    
    
    int main()
    {
    
      inta f[50][50];
    
      for(int i=0;i<50;i++)
        for(int j=0;j<50;j++)
             f[i][j]=0;
    
      f[0][0]=1;
    
      for(int i=0;i<50;i++)
        for(int j=0;j<=i;j++)
          {
            if(i>0) f[i][j]+=f[i-1][j];
            if(j>0) f[i][j]+=f[i][j-1];
          }
    
       for(int i=0;i<50;i++)
         cout<<f[i][i]<<endl;
    }
    



  • 相关阅读:
    ActiveX控件开发总结(续)
    Guru of the Week 条款04: 类的构造技巧
    tk
    C++中一个空类的大小为什么是1?
    虚继承
    计算机单位
    Guru of the week:#18 迭代指针.
    kingofark关于学习C++和编程的50个观点
    Guru of the Week 条款06:正确使用const
    Guru of the Week 条款07:编译期的依赖性
  • 原文地址:https://www.cnblogs.com/814jingqi/p/3247191.html
Copyright © 2020-2023  润新知