题意:
给定一个字母集合:
乘法规则如下:
求一个字符串通过加括号的方法,得到 a ,有多少种方案。
这个问题和矩阵连乘问题很类似。
刚开始我想错了,d(i,j),前 i 个字符形成 j 字符的方案数,这个状态的定义是有问题的,问题在于,状态转移,只能是d(i+1,j) 到 d(i,),也就是说,
乘法规则只能是从左到右。
正确方案:
d(i,j,k) i~j 字符形成 k 的方案数,这样,就和矩阵连乘的状态转移很类似了。

1 #include <bits/stdc++.h> 2 3 using namespace std; 4 5 const int maxn = 1000; 6 int dp[maxn][maxn][3]; 7 char str[maxn]; 8 9 int main() { 10 11 memset(dp,0,sizeof(dp)); 12 scanf("%s",str); 13 14 int len = strlen(str); 15 for(int i=0;i<len;i++) { 16 if(str[i]=='a') dp[i][i][0] = 1; 17 else if(str[i]=='b') dp[i][i][1] = 1; 18 else if(str[i]=='c') dp[i][i][2] = 1; 19 } 20 21 for(int r=2;r<=len;r++) { 22 for(int i=0;i+r-1<=len-1;i++) { 23 int k = i + r - 1; 24 for(int j=i+1;j<=k;j++) { 25 dp[i][k][0]+= (dp[i][j-1][0]*dp[j][k][2] + dp[i][j-1][1]*dp[j][k][2] + dp[i][j-1][2]*dp[j][k][0]); 26 dp[i][k][1]+= (dp[i][j-1][0]*dp[j][k][0] + dp[i][j-1][0]*dp[j][k][1] + dp[i][j-1][1]*dp[j][k][1]); 27 dp[i][k][2]+= (dp[i][j-1][1]*dp[j][k][0] + dp[i][j-1][2]*dp[j][k][1] + dp[i][j-1][2]*dp[j][k][2]); 28 } 29 } 30 } 31 printf("%d ",dp[0][len-1][0]); 32 return 0; 33 }