poj3280——cheapest palindrome

题目大意:在原字符串中添加或删除字母,使其成为回文串,添加、删除每个字母的代价不同,问最小代价是多少

输入:原字符串包含的字母种类数N 原字符串长度M(1<=N<=26)(1<=M<=2000)

          原字符串

          第i种字母 添加代价 删除代价(0<=cost<=10000)

输出:最小代价

分析:区间动态规划

          状态dp[i][j]:i到j变为回文串的最小代价

          结果:dp[0][m-1]

          初始化:dp[i][i]=0

          状态转移方程:if(s[i]=s[j]) dp[i][j]=dp[i+1][j-1]                         //前后匹配

                                else dp[i][j]=min{ dp[i+1][j]+min{add[i],del[i]},  //不匹配,添加或删除s[i]使成为回文串

                                                           dp[i][j-1]+min{add[j],del[j]} }  //不匹配,添加或删除s[j]使成为回文串

代码:转载自http://blog.csdn.net/y990041769/article/details/24259569(有稍加改动)


#include <cstdio>  
#include <string>  
#include <iostream>  
#include <algorithm>  
#include <cstring>  
using namespace std;  
const int N = 200;  
const int M = 2500;  
int add[N];  
int dp[M][M];  
  
int main()  
{  
    int n,m;  
    string s;  
    while(~scanf("%d%d",&n,&m))  
    {  
        cin>>s;  
        char c;int x,y;  
        for(int i=0;i<n;i++)  
        {  
            cin>>c>>x>>y;  
            add[c]=min(x,y);  
        }  
        memset(dp,0,sizeof(dp));  
        for(int k=1;k<s.size();k++)  
        {  
            for(int i=0,j=k;j<s.size();i++,j++)  
            {  
                dp[i][j]=0x3f3f3f3f;  
                if(s[i]==s[j])  
                    dp[i][j]=dp[i+1][j-1];  
                else  
                {  
                    dp[i][j]=min(dp[i+1][j] + add[s[i]],dp[i][j]);  
                    dp[i][j]=min(dp[i][j-1] + add[s[j]],dp[i][j]);  
                }  
            }  
        }  
        printf("%d\n",dp[0][s.size()-1]);  
    }  
    return 0;  
}


 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值