关于括号式子的计数

原创 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语言】计算器(支持括号和长式子)

支持括号的计算器 没有成功,写篇总结
  • weixin_39114797
  • weixin_39114797
  • 2017年11月18日 18:21
  • 60

关于数学公式输入中括号的换行问题 的两种常用方法

LaTeX最为擅长的就是数学公式的精彩输出,美观,漂亮。但是大公式的处理是很多用户比较棘手的问题,比如下面这个问题, 通常我们输入的大公式,主要有两种情况比较难处理: 1、因为长的分式,比如一个非...
  • i10630226
  • i10630226
  • 2015年03月28日 10:25
  • 1427

latex 大括号中公式换行,拆分公式,公式换行

latex 中一般的公式拆分可以用 multline 或 split,区别在于公式编码显示的位置不同,前者编码在换行的最后一行,后者编码在整个换行公式的中间。然而,因为不能与align alignat...
  • robert_chen1988
  • robert_chen1988
  • 2016年10月09日 02:08
  • 5331

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

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

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

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

帮朋友解答一道题~输入String的运算公式直接输出结果

package testAndfun; import java.util.Stack; public class operator { public static void main(Strin...
  • qbt4juik
  • qbt4juik
  • 2015年02月06日 18:26
  • 917

Java提取中括号中的内容

曾经在工作中遇到一个问题,就是需要一个字符串中每一个中括号里的内容,在网上搜了一下,发现用正则表达式可以提取中括号中的内容,具体实现如下: {CSDN:CODE:1829481} 输出结果如下:...
  • tianpy5
  • tianpy5
  • 2016年08月14日 19:33
  • 10406

正则表达式(括号)、[中括号]、{大括号}的区别小结

正则表达式的() [] {}有不同的意思。 () 是为了提取匹配的字符串。表达式中有几个()就有几个相应的匹配字符串。 (\s*)表示连续空格的字符串。 []是定义匹配的字符范围。比如 [a-z...
  • u010552788
  • u010552788
  • 2016年03月30日 21:11
  • 13889

shell中单中括号与双中括号的区别

1.单括号TEST命令要对变量进行单词分离,当变量值包含空白符时,要用引号将变量括起来;而双括号的TEST命令不会对变量进行单词分离。 以下情况分为变量为单个单词,含有空格的词组。 [ro...
  • good_habits
  • good_habits
  • 2014年05月30日 20:39
  • 2505

php中return,require,include加括号和不加括号的区别

php中return,require,include加括号和不加括号的区别 2010年6月30日小旅发表评论阅读评论 在整理代码规范的时候看到这么一句,return返回值尽量不...
  • zha_stef
  • zha_stef
  • 2014年08月14日 15:27
  • 1914
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:关于括号式子的计数
举报原因:
原因补充:

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