题目大意:给定一个字符串S及其长度M与S所含有的字符种数N(最多26种小写字母),然后给定这N种字母Add与Delete的代价,求将S变为回文串的最小代价和。
思路:其实这题就是基于求LCS基础上再添加上每个字母删除增加的价格和最小。
求回文串方法:将当前字符串S反转成S',求出最长公共字串长度l1,用总长L-l1即需要改变的字母个数。
代码实现:
if(s[i]==s[j])
dp[i][j]=dp[i+1][j-1];
else
dp[i][j]=min(dp[i+1][j]+min(add[i],delete[i]),dp[i][j-1]+min(add[j],delete[j]));
AC代码:
#include <iostream>
#include <iomanip>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <cstdlib>
using namespace std;
int dp[2005][2005],n,m;
struct al
{
int add,deletee;
}a[27];
char s[2005];
int main()
{
scanf("%d%d",&n,&m);
scanf("%s",s);
for(int i=1;i<=n;i++)
{ char cc;
cin>>cc;
cin>>a[cc-'a'].add>>a[cc-'a'].deletee;
}
for(int i=1;i<m;i++)
for(int j=0;j+i<m;j++)
if(s[j]==s[j+i])
dp[j][j+i]=dp[j+1][i+j-1];
else//避免min嵌套 dp[i][j]=min((dp[i+1][j]+min(a[s[i]-'a'].add,a[s[i]-'a'].deletee)),(dp[i][j-1]+min(a[s[j]-'a'].add,a[s[j]-'a'].deletee)));
{
int x=dp[j+1][j+i]+min(a[s[j]-'a'].add,a[s[j]-'a'].deletee);
int y=dp[j][j+i-1]+min(a[s[j+i]-'a'].add,a[s[j+i]-'a'].deletee);
dp[j][j+i]=min(x,y);
}
cout<<dp[0][m-1]<<endl;
}