关于括号式子的计数

原创 2007年09月30日 22:02:00
  • CSDN
  • CSDN社区
  • 专题开发/技术/项目
  • 数据结构与算法
  • 超超版主的问题:

    如果有n对括号,组成一个式子,而且括号的最深嵌套层次为k
    满足这个条件的式子一共有几种?
    如果n=3,k=2则有3种:
    (())()
    ()(())
    (()())

    能否找到递推公式? 

    ------------------------------------------------------------------------------------------

    tailzhou  网友的解答:

    对于特定的 n,k;
    深度为k的子式子最少有k个括号,最多有n个括号

    对由i(i >=k and i <=n)个括号组成的深度为k的式子可以由dp数组得到;
    其他的n-i个括号分布在深度为k的子式子的前后;

    为了不重复统计,规定上面深度为k的子式子是 大式子中的第一个深度为k的子式子;

    分别对前面有j(j >=0,j <=n-i,并且这k个括号组成的式子的最大深度不能大于k-1,也就是最大深度从1到k-1的总数的和)个括号,后面有n-i-j(并且这n-i-j个括号组成的式子的最大深度不能大于k)个括号的情况统计;


    #include  <stdio.h >

    #define MAX_N 20

    int dp[MAX_N+1][MAX_N+1];

    void fun(int n,int k)
    {
    int i,j;
    for (i=k;i <n;++i)
    {
    int tmp=0;

    for (j=0;j <=n-i;++j)
    {
      int tmp_i=j;
    int tmp_j=n-i-j;
    int tmp_k1=0,tmp_k2=0;
    if (tmp_i >k-1) tmp_i=k-1;
    if (tmp_j >k) tmp_j=k;

    for (;tmp_i >0 ; tmp_i--)
    {
    tmp_k1+=dp[j][tmp_i];
    }
    for (;tmp_j >0 ; tmp_j--)
    {
    tmp_k2+=dp[n-i-j][tmp_j] ;
    }

    if (tmp_k1 <1) tmp_k1=1;
    if (tmp_k2 <1) tmp_k2=1;

    tmp+=tmp_k1*tmp_k2;

    }
    dp[n][k]+=dp[i-1][k-1]*tmp;
    }
    dp[n][k]+=dp[n-1][k-1];
    }

    int main(int argc, char* argv[])
    {

    //最深嵌套层次为k,那么肯定存在一个层次为k-1的式子,其外围再有一对括号;
    //这对括号外再没有嵌套的括号;
    int n,k;

    for (n=1; n <=MAX_N; n++)
    {
    dp[n][1]=1;
    dp[n][n]=1;
    }

    for (n=1; n <=MAX_N; n++)
    {
    for (k=1; k <=n; k++)
    {
    if (k!=n && k!=1) fun(n,k);

    printf("n:%3d k:%3d dp:%10d/n",n,k,dp[n][k]);
    }
    }

    fun(20,2);

    printf("input n{max:%d} and k{max:%d}:",MAX_N,MAX_N);
    while (scanf("%d %d",&n,&k)==2)
    {
    printf("%d %d : %d /n" ,n,k,dp[n][k]);
    printf("input n{max:%d} and k{max:%d}:",MAX_N,MAX_N);
    }

    return 0;
    }

    顺手将其改写成VB代码,如下所示:

    Sub fun(ByVal n As Long, ByVal k As Long, ByRef dp())
    Dim i As Long, j As Long, temp As Long, temp_i As Long, temp_j As Long, temp_k1 As Long, temp_k2 As Long
    For i = k To n - 1
    temp = 0
    For j = 0 To n - i
    temp_i = j
    temp_j = n - i - j
    temp_k1 = 0
    temp_k2 = 0
    If temp_i > k - 1 Then temp_i = k - 1
    If temp_j > k Then temp_j = k
    While temp_i > 0
    temp_k1 = temp_k1 + dp(j, temp_i)
    temp_i = temp_i - 1
    Wend
    While temp_j > 0
    temp_k2 = temp_k2 + dp(n - i - j, temp_j)
    temp_j = temp_j - 1
    Wend
    If temp_k1 < 1 Then temp_k1 = 1
    If temp_k2 < 1 Then temp_k2 = 1
    temp = temp + temp_k1 * temp_k2
    Next
    dp(n, k) = dp(n, k) + dp(i - 1, k - 1) * temp
    Next
    dp(n, k) = dp(n, k) + dp(n - 1, k - 1)
    End Sub


    Sub main()
    Dim n As Long, k As Long, max_n As Long
    max_n = 23
    ReDim dp(1 To max_n, 1 To max_n)
    For n = 1 To max_n
    dp(n, 1) = 1
    dp(n, n) = 1
    Next
    For n = 1 To max_n
    For k = 1 To n
    If k > 1 And k < n Then fun n, k, dp
    Next
    Next
    [a1].Resize(max_n, max_n) = dp
    [a1].Resize(max_n, max_n).Columns.AutoFit
    End Sub

    在EXCEL中返回:

    1                                            
    1 1                                          
    1 3 1                                        
    1 7 5 1                                      
    1 15 18 7 1                                    
    1 31 57 33 9 1                                  
    1 63 169 132 52 11 1                                
    1 127 482 484 247 75 13 1                              
    1 255 1341 1684 1053 410 102 15 1                            
    1 511 3669 5661 4199 1975 629 133 17 1                          
    1 1023 9922 18579 16017 8778 3366 912 168 19 1                        
    1 2047 26609 59917 59224 36938 16422 5358 1267 207 21 1                      
    1 4095 70929 190696 214058 149501 75140 28405 8099 1702 250 23 1                    
    1 8191 188226 600744 760487 587951 328185 140049 46305 11753 2225 297 25 1                  
    1 16383 497845 1877256 2665884 2262375 1384345 654588 244412 72036 16500 2844 348 27 1                
    1 32767 1313501 5828185 9246276 8558854 5685306 2937932 1215448 404984 107880 22536 3567 403 29 1              
    1 65535 3459042 17998783 31793724 31945379 22863861 12776589 5773812 2133296 643280 156519 30073 4402 462 31 1            
    1 131071 9096393 55342617 108548332 117939506 90420110 54190390 26457508 10683684 3576375 986391 221067 39339 5357 525 33 1          
    1 262143 23895673 169552428 368400045 431530926 352754930 225253075 117789057 51401251 18822825 5770224 1467864 305102 50578 6440 592 35 1        
    1 524287 62721698 517884748 1244027317 1567159901 1360882980 921000186 512231849 239414383 94817125 31831137 9011054 2128646 412698 64050 7659 663 37 1      
    1 1048575 164531565 1577812060 4182854728 5655480303 5201391077 3714710824 2184870646 1085877703 460879770 167490453 51981891 13681044 3018092 548457 80031 9022 738 39 1    
    1 2097151 431397285 4796682165 14012220027 20299352107 19724548877 14812754293 9170250565 4817505085 2175127695 847842567 285135279 82362071 20265685 4195037 717541 98813 10537 817 41 1  
    1 4194303 1130708866 14555626635 46789129817 72522832282 74300429926 58500857880 37970054320 20980377935 10015603001 4155948108 1500475196 470125106 127088478 29373300 5728932 925704 120704 12212 900 43 1

    相关文章推荐

    c/c++表达式求值,即包含加减乘除以及括号的式子(栈)

    首先要了解前缀表达式,中缀表达式,后缀表达式 其实三者的区别用一句话就可概括,中缀表达式是给人算的,前缀,后缀表达式是给计算机计算的 它们都是对表达式的记法,因此也被称为前缀记法、中缀记法和后缀记...

    H. Zé Coquinho, the sculptor 计数 括号题 2010 USP Try-outs

    题意:输入n,K,求第K大的非法括号序列,若没有第K大,输出-1。题目保证运算的数据都在long long范围内。 解法: 1. 如果n为奇数,那么所有的序列都是非法的,令右括号为二进制1,左括号...

    UVA 10700 Camel trading(计算式子加减乘除的优先级处理)

    Camel trading Time Limit: 1 second Background Aroud 800 A.D., El Mamum, Calif o...

    随机生成加减乘除混合运算加减乘除数学式子题目答案批量生成工具软件使用方法

    欢迎使用由未来自主研究中心(FIRC)强力打造的小学生加减乘除数学计算工具,使用方法如下: 最大数 最大数是指数学式子中可能出现的最大数字,注意这里是可能,也就是说式子中最大只可能是指定的数字,例如选...

    如何辨认一个复杂声明表达式子中变量的类型?

    何谓复杂声明表达式子中变量的类型?先来看看这段代码:typedef double* (*a)[10]; typedef int* (*b[10])[10]; typedef int(*(*c)(int...

    div+css 制作隐藏式子菜单

    • 2011年06月02日 09:59
    • 8KB
    • 下载

    特定式子的非线性拟合(使用于数据较少的的时候)

    问题:有些时候我们需要拟合一些非线性的表达式。 比如:我们知道一个表达式的式子是y=A*sin(x).*exp(x)-B./log(x),现在我们手里面有x与y对应的一大把数据。我们如何根据x,y的值...

    将浮点型算式的中缀表达式转换成后缀表达式并算出式子结果

    最近因为需要了解如何将在Win应用程序控制台输入的算式表达式转化成其后缀表达式的算法,所以在网上搜索了一下,看到许多人的程序都只是对应于运算数在0~9的范围内的整型运算式,所以自己就写了一个可以计算浮...

    由数字式子生成对应的二叉树

    /*由式子生成二叉树*/ //例如输入:1-2*3+4/(5+6)-7*8# #include #include ///////////////////////////////////////////...

    椭圆拟合的函数式子以及绘制外接矩形

    首先是在二值图像中找轮廓,我的图象中只有一条轮廓,所以使用比较简单。 首先要分配存储空间,使用函数cvCreateMemStorage(0)分配一个默认大小的CvMemStorage型空间。 然后...
    内容举报
    返回顶部
    收藏助手
    不良信息举报
    您举报文章:关于括号式子的计数
    举报原因:
    原因补充:

    (最多只允许输入30个字)