poj 3280-回文串-DP

来源:互联网 发布:js中readonly 编辑:程序博客网 时间:2024/06/01 08:29

题意:对一个字符串进行插入删除等操作使其变成一个回文串,但是对于每个字符的操作消耗是不同的。求最小消耗.

显然是一个dp问题,可以设定状态dp[i][j]表示从i~j这一段变成回文的最小消耗,显然状态转移就是

[cpp] view plaincopy
  1. if(s[i]==s[j])dp[i][j]=dp[i+1][j-1];  
  2. else  
  3. dp[i][j]=min(dp[i+1][j]+w[s[i]-'a'],dp[i][j-1]+w[s[j]-'a']);  
虽然删除和插入不同,但是这两种操作是等价的,这头加和那头减是一样的,所以开始的时候只要取这两种操作的最小值就ok了。

[cpp] view plaincopy
  1. #include<cstdio>  
  2. #include<string>  
  3. #include<cstring>  
  4. #include<cmath>  
  5. #include<iostream>  
  6. #include<algorithm>  
  7. using namespace std;  
  8. int w[30],n,m,dp[2005][2005];  
  9. char s[2005],ch;  
  10. int main()  
  11. {  
  12.     int x,y;  
  13.     while(scanf("%d%d",&m,&n)!=EOF)  
  14.     {  
  15.         getchar();  
  16.         scanf("%s",s);  
  17.         getchar();  
  18.         for(int i=0;i<m;i++)  
  19.         {  
  20.             scanf("%ch",&ch);  
  21.             scanf("%d%d",&x,&y);  
  22.             getchar();  
  23.             w[ch-'a']=min(x,y);  
  24.         }  
  25.         for(int i=n-1;i>=0;i--)  
  26.             for(int j=i+1;j<n;j++)  
  27.             {  
  28.                 if(s[i]==s[j])dp[i][j]=dp[i+1][j-1];  
  29.                 else  
  30.                     dp[i][j]=min(dp[i+1][j]+w[s[i]-'a'],dp[i][j-1]+w[s[j]-'a']);  
  31.             }  
  32.             printf("%d\n",dp[0][n-1]);  
  33.     }  
  34.     return 0;  
  35. }
原文来自:http://blog.csdn.net/xymscau/article/details/6733524
0 0
原创粉丝点击