原题链接
想变成回文串增加或删除一个字符的作用效果相同,所以存的时候只用存下来增加和删除里面花费比较少的一项。因为不匹配时删除一个字符和增加一个字符效果相同,所以我们贪心的往字符串上添加字符就好了;
然后就是动态规划的方程了;
看代码:
#include <iostream>
#include <string>
#include <algorithm>
using namespace std;
const int maxn=200;
int money[maxn];
int dp[2005][2005];
int main()
{
int n,m;
cin>>n>>m;
string s;
cin>>s;
for(int i=0;i<=m;i++){
for(int j=0;j<=m;j++){
dp[i][j]=0;
}
}
for(int i=0;i<n;i++){
char ch;
int a,b;
cin>>ch>>a>>b;
money[ch]=min(a,b);
}
//子串长度为1;
for(int i=0;i<m;i++){
dp[i][i]=0;
}
//子串长度为2;
for(int i=1;i<m;i++){
if(s[i-1]!=s[i])
dp[i-1][i]=min(money[s[i-1]],money[s[i]]);
}
//子串长度一次递增;
for(int k=2;k<m;k++){
// cout<<"k="<<k<<endl;
for(int i=0,j=i+k;i<m&&j<m;i++,j++){
if(s[i]==s[j]){
dp[i][j]=dp[i+1][j-1];
}
else{
dp[i][j]=min(dp[i+1][j]+money[s[i]],dp[i][j-1]+money[s[j]]);
//cout<<s[i]<<" "<<s[j]<<endl;
//cout<<dp[i][j]<<endl;
}
}
}
cout<<dp[0][m-1];
return 0;
}