//目录

乘法表问题

题意:

给定一个字母集合:

乘法规则如下:

求一个字符串通过加括号的方法,得到 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\n",dp[0][len-1][0]);
32     return 0;
33 }
View Code

 

posted @ 2017-03-24 16:54  小草的大树梦  阅读(412)  评论(0编辑  收藏  举报