• 乘法表问题


    题意:

    给定一个字母集合:

    乘法规则如下:

    求一个字符串通过加括号的方法,得到 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 }
    View Code
  • 相关阅读:
    一、列表
    正则表达式
    form表单学习
    HTTP场景应用
    fiddler几种功能强大的用法(二)
    在VMW里安装Ghost操作系统遇到的问题及解决的办法
    浮点数值的表示
    补码和补码的计算
    个人主页项目总结
    Todolist项目总结 JavaScript+jQuery
  • 原文地址:https://www.cnblogs.com/TreeDream/p/6612328.html
Copyright © 2020-2023  润新知