这个题其实跟“矩阵连乘”问题很接近,它的递推结构是:A[i][j][dest]=A[i][k][p]+A[k+1][j][q],其中A[i]
[j][dest]表示字符串xi...xj导出结果为dest(dest取值为0 1 2,分别对应'a' 'b' 'c')的加括号方法数。
下面是我的c代码,在VC6.0和gcc 2.95.3-5下测试通过:
/
************************************************************************/
/* 乘法表问题 */
/
************************************************************************/
#include "stdio.h"
#include <string.h>
#define max_length 100
int table[3][3]={{1,1,0},{2,1,0},{0,2,2}};//乘法表,a b c 分别对应 0 1 2
int A[max_length][max_length][3];//表示字符串到a b c的不同的加括号方法
int calculate(int* x,int n,int dest){//dest取值为0 1 2,表示x(i,j)到dest的不同加括号
方法
int num=0;
int i=1,j=1;
int r=0;
for(r=2;r<=n;r++)//个数
for(i=0;i<=n-r;i++){
j=i+r-1;
int k=0;
for(k=i;k<j;k++){
int p=0,q=0,m=0;
for(m=0;m<3;m++)
for(p=0;p<3;p++)//查表
for(q=0;q<3;q++){
if(table[p][q]==m)
A[i][j][m]+=A[i][k][p]*A[k+1][j][q];
}
}
}
return A[0][n-1][dest];
}
int main()
{
int x[max_length];
memset(x,0,sizeof(x));
int i=0,j=0;
char c;
while((c=getchar())!='\n'){//如果是从文件读取就是!=EOF
switch(c) {
case 'a':
x[i]=0;
break;
case 'b':
x[i]=1;
break;
case 'c':
x[i]=2;
break;
default:
break;
}
i++;
}
int n=i;
memset(A,0,sizeof(A));
for(i=0;i<n;i++){
A[i][i][x[i]]=1;//(i,i)只有一个元素,它到x[i]的加括号方法为1
}
printf("%d\n",calculate(x,n,0));//到a的加括号方法数
return 0;
}