1. 程式人生 > >[luoguP2890] [USACO07OPEN]便宜的回文Cheapest Palindrome(DP)

[luoguP2890] [USACO07OPEN]便宜的回文Cheapest Palindrome(DP)

span char play click aps cst 代碼 include sdi

傳送門

f[i][j] 表示區間 i 到 j 變為回文串所需最小費用

1.s[i] == s[j]  f[i][j] = f[i + 1][j - 1]

2.s[i] != s[j]  f[i][j] = min(f[i + 1][j] + cost[s[i]], f[i][j - 1] + cost[s[j]])

開頭去掉一個字母和結尾增加一個字母的效果是一樣的

所以 cost[s[i]] = min(add[s[i]], del[s[i]])

——代碼

技術分享
 1 #include <cstdio>
 2 #include <cstring>
 3
#include <iostream> 4 5 int n, m; 6 int a[301], f[2010][2010]; 7 char s[2010]; 8 9 inline int read() 10 { 11 int x = 0, f = 1; 12 char ch = getchar(); 13 for(; !isdigit(ch); ch = getchar()) if(ch == -) f = -1; 14 for(; isdigit(ch); ch = getchar()) x = (x << 1
) + (x << 3) + ch - 0; 15 return x * f; 16 } 17 18 inline int min(int x, int y) 19 { 20 return x < y ? x : y; 21 } 22 23 inline int dp(int x, int y) 24 { 25 if(x >= y) return f[x][y] = 0; 26 if(f[x][y] ^ -1) return f[x][y]; 27 if(s[x] == s[y]) return f[x][y] = dp(x + 1
, y - 1); 28 else return f[x][y] = min(dp(x + 1, y) + a[s[x]], dp(x, y - 1) + a[s[y]]); 29 } 30 31 int main() 32 { 33 int i; 34 char c[1]; 35 n = read(); 36 m = read(); 37 scanf("%s", s + 1); 38 for(i = 1; i <= n; i++) 39 { 40 scanf("%s", c); 41 a[c[0]] = min(read(), read()); 42 } 43 memset(f, -1, sizeof(f)); 44 printf("%d\n", dp(1, m)); 45 return 0; 46 }
View Code

[luoguP2890] [USACO07OPEN]便宜的回文Cheapest Palindrome(DP)