乘法表问题

题意:

给定一个字母集合:

乘法规则如下:

求一个字符串通过加括号的方法,得到 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

 

转载于:https://www.cnblogs.com/TreeDream/p/6612328.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值