题意:给你m个字符,其中有n种字符,每种字符都有两个值,分别是增加一个这样的字符的代价,删除一个这样的字符的代价,让你求将原先给出的那串字符变成回文串的最小代价。
思路:区间DP,dp[i][j]代表将区间[i,j]变为回文串的最小代价。
#include <string.h> #include <stdio.h> #include <stdlib.h> #include <math.h> #include <iostream> #include <queue> #include <algorithm> #define MAXSIZE 2005 #define LL long long #define INF 0x3f3f3f #define mod 10056 using namespace std; /*给你m个字符,其中有n种字符,每种字符都有两个值, 分别是增加一个这样的字符的代价,删除一个这样的字符的代价, 让你求将原先给出的那串字符变成回文串的最小代价。*/ int dp[MAXSIZE][MAXSIZE],a[MAXSIZE],add[MAXSIZE],red[MAXSIZE],n,m; char s[MAXSIZE]; int Solve() { memset(dp,0,sizeof(dp)); for(int i=m-1;i>=1;i--) { for(int j=i+1;j<=m;j++) { dp[i][j] = min(dp[i+1][j] + add[s[i]-'a'],dp[i+1][j] + red[s[i]-'a']); //删除s[i]或增加s[i] dp[i][j] = min(dp[i][j],dp[i][j-1] + red[s[j]-'a']);//删除s[j] dp[i][j] = min(dp[i][j],dp[i][j-1] + add[s[j]-'a']);//增加s[j] if(s[i] == s[j]) dp[i][j] = min(dp[i][j] ,dp[i+1][j-1]); } } return dp[1][m]; } int main() { char ch[1]; while(scanf("%d%d",&n,&m)!=EOF) { scanf("%s",s+1); for(int i=1;i<=n;i++) { scanf("%s",ch); scanf("%d%d",&add[(ch[0]-'a')],&red[(ch[0]-'a')]); } int ans = Solve(); printf("%d ",ans); } return 0; }