这这这,又是括括号的题型,我们枚举用状态方程枚举每一个括括号的结果次数即可。这里我们做一个三维数组即可。每一层代表一个字母,并且用0和1代表该字母是否存在作为初始化,我们的状态转移方程类似于矩阵链乘问题,哈哈哈。
具体如下
dp[i][j][0]+=dp[i][k][0]*dp[k+1][j][2]+dp[i][k][1]*dp[k+1][j][2]+dp[i][k][2]*dp[k+1][j][0]; dp[i][j][1]+=dp[i][k][0]*dp[k+1][j][0]+dp[i][k][0]*dp[k+1][j][1]+dp[i][k][1]*dp[k+1][j][1]; dp[i][j][2]+=dp[i][k][1]*dp[k+1][j][0]+dp[i][k][2]*dp[k+1][j][1]+dp[i][k][2]*dp[k+1][j][2];
这个是我们依旧题目给出的表得出的乘法公式,dp[i][j]代表我们的加括号的总次数。存在最优子结构。
具体分析看上一篇,矩阵链问题,并且这道题有两种推演方式。
但这里只给一种,另一种各位自己可以推一推。嘿嘿。
#include<bits/stdc++.h>
using namespace std;
int dp[100][100][3];
int main()
{
string a;
cin>>a;
for(int i=1;i<=a.size();i++)
{
if(a[i-1]=='a')
dp[i][i][0]=1;
else dp[i][i][0]=0;
if(a[i-1]=='b')
dp[i][i][1]=1;
else dp[i][i][1]=0;
if(a[i-1]=='c')
dp[i][i][2]=1;
else dp[i][i][2]=0;
}
int num=a.size();
for(int r=2;r<=a.size();r++)
{
for(int i=1;i<=a.size()-r+1;i++)
{
int j=i+r-1;
for(int k=i;k<=j;k++)
{
dp[i][j][0]+=dp[i][k][0]*dp[k+1][j][2]+dp[i][k][1]*dp[k+1][j][2]+dp[i][k][2]*dp[k+1][j][0];
dp[i][j][1]+=dp[i][k][0]*dp[k+1][j][0]+dp[i][k][0]*dp[k+1][j][1]+dp[i][k][1]*dp[k+1][j][1];
dp[i][j][2]+=dp[i][k][1]*dp[k+1][j][0]+dp[i][k][2]*dp[k+1][j][1]+dp[i][k][2]*dp[k+1][j][2];
}
}
}
cout<<dp[1][a.size()][0]<<endl;
}