POJ 3280 Cheapest Palindrome(区间dp)
dp[i][j]表示处理完i到j的花费,如果s[i] == s[j] 则不需要处理,否则处理s[i]或s[j],
对一个字符ch,加上ch或删掉ch对区间转移来说效果是一样的,两者取min。
#include<cstdio> #include<iostream> #include<string> #include<cstring> #include<queue> #include<vector> #include<stack> #include<vector> #include<map> #include<set> #include<algorithm> using namespace std; const int sigma_size = 26, maxm = 2e3+5; char s[maxm]; int add[sigma_size], del[sigma_size]; int cost[sigma_size]; int dp[maxm][maxm]; //#define LOCAL int main() { #ifdef LOCAL freopen("in.txt","r",stdin); #endif int n, m; scanf("%d%d",&n,&m); scanf("%s",s); for(int i = n; i--;){ char ch[2]; scanf("%s",ch); int id = *ch-'a'; scanf("%d%d",add+id,del+id); cost[id] = min(add[id],del[id]); } for(int L = 1; L < m; L++){ for(int i = 0; i+L < m; i++){ int j = i+L; if(s[i] == s[j]){ dp[i][j] = dp[i+1][j-1]; // 可能会有i+1 = j, j-1 = i,但是最初是0所以没有影响 }else { dp[i][j] = min(dp[i+1][j] + cost[s[i]-'a'], dp[i][j-1] + cost[s[j]-'a']) ; } } } printf("%d\n",dp[0][m-1]); return 0; }