POJ 3280 Cheapest Palindrome

来源:互联网 发布:大屏播放软件 编辑:程序博客网 时间:2024/06/05 05:59

题意:有n种字符,组成长为m的串,分别给出字符增加和删除操作的代价,求把原字符串变成回文串的最小代价

解题思路:区间dp.dp[i][j]表示从区间i到j是一个回文串的最小代价,状态转移方程是:如果s[i]=s[j],dp[i][j]=dp[i+1][j-1];否则dp[i][j]=min(dp[i][j],dp[i+1][j]+min(add[s[i]-'a'],del[s[i]-'a']))),dp[i][j]=min(dp[i][j],dp[i][j-1]+min(add[s[j]-'a'],del[s[j]-'a'])).区间dp就是将一个区间划分成很多个小区间进行求解

代码:

#include <iostream>#include <algorithm>#include <cstring>#include <string>#include <cstdio>#include <cmath>using namespace std;#define INF 0x3f3f3f3fconst int maxn=30;const int maxm=2000+5;int n,m;string s;int add[maxn],del[maxn];int dp[maxm][maxm];void solve(){    int ans=0;    for(int i=m-1;i>=0;i--)    {        dp[i][i]=0;        for(int j=i+1;j<m;j++)        {            dp[i][j]=INF;            if(s[i]==s[j])dp[i][j]=dp[i+1][j-1];            else            {                dp[i][j]=min(dp[i][j],dp[i+1][j]+min(add[s[i]-'a'],del[s[i]-'a']));                dp[i][j]=min(dp[i][j],dp[i][j-1]+min(add[s[j]-'a'],del[s[j]-'a']));            }        }    }    printf("%d\n",dp[0][m-1]);}int main(){    while(cin>>n>>m)    {        cin>>s;        char ch;        int a,b;        for(int i=0;i<n;i++)        {            cin>>ch>>a>>b;            add[ch-'a']=a;            del[ch-'a']=b;        }        solve();    }    return 0;}/*3 4abcba 1000 1100b 350 700c 200 800*/


原创粉丝点击