POJ 3280 Cheapest Palindrome(DP 回文变形)
题目链接:http://poj.org/problem?id=3280
题目大意:给定一个字符串,可以删除增加,每个操作都有代价,求出将字符串转换成回文串的最小代价
Sample Input
3 4 abcb a 1000 1100 b 350 700 c 200 800
Sample Output
900
分析:这是一道最长回文串的变形,就是LCS
一串字符要变成回文,对于一个字符来说,删掉它,或者增加对称的一个该字符,都能达到回文的效果,所以是等价的。所以取代价的的时候选择最小的就可以。
至于动态规划方程:令dp[i][j]表示从第 i 个字符到第j个字符变成回文的最小代价,初始为0。接着LCS
dp[i][j] = min(dp[i+1][j]+cost[s[i]-'a'] , dp[i][j-1]+cost[s[j]-'a']) ;
if(s[i]==s[j]) dp[i][j] = min(dp[i+1][j-1],dp[i][j]);
代码如下:
1 # include<stdio.h> 2 # include<string.h> 3 # define maxn 2005 4 char s[maxn]; 5 int dp[maxn][maxn],cost[maxn]; 6 7 int min(int a,int b){ 8 return a<b ? a :b; 9 } 10 11 int main(){ 12 int n,m,a,b,i,j; 13 char temp; 14 while(scanf("%d%d",&n,&m)!=EOF){ 15 memset(dp,0,sizeof(dp)); 16 getchar(); 17 scanf("%s",s+1); 18 getchar(); 19 for(i=1;i<=n;i++){ 20 scanf("%c %d%d",&temp,&a,&b); 21 getchar(); 22 cost[temp-'a'] = min(a,b); 23 } 24 for(j=1;j<=m;j++){ 25 for(i=j+1;i>=1;i--){ 26 dp[i][j] = min(dp[i+1][j]+cost[s[i]-'a'] , dp[i][j-1]+cost[s[j]-'a']) ; 27 if(s[i]==s[j]) 28 dp[i][j] = min(dp[i+1][j-1],dp[i][j]); 29 } 30 } 31 printf("%d\n",dp[1][m]); 32 } 33 return 0; 34 }
把每一件简单的事情做好,就是不简单;把每一件平凡的事情做好,就是不平凡!相信自己,创造奇迹~~