uva 10739 String to Palindrome

原题:
In this problem you are asked to convert a string into a palindrome with minimum number of operations.
The operations are described below:
Here you’d have the ultimate freedom. You are allowed to:
• Add any character at any position
• Remove any character from any position
• Replace any character at any position with another character
Every operation you do on the string would count for a unit cost. You’d have to keep that as low
as possible.
For example, to convert “abccda” you would need at least two operations if we allowed you only to
add characters. But when you have the option to replace any character you can do it with only one
operation. We hope you’d be able to use this feature to your advantage.
大意:
给你一个字符串,让你随意添加,删除,替换,问你最少多少步操作能把这个字符串变成回文。

#include<iostream>
#include<algorithm>
#include<map>
#include<string>
#include<cstring>
#include<sstream>
#include<cstdio>
#include<vector>
#include<cmath>
#include<stack>
#include<queue>
#include<iomanip>
#include<set>
#include<fstream>
using namespace std;

int dp[1001][1001];
int min3(int x,int y,int z)
{
    return min(min(x,y),min(x,z));
}
int main()
{
    ios::sync_with_stdio(false);
    int n;
    string s;
    cin>>n;
    for(int k=1;k<=n;k++)
    {
        cin>>s;
        memset(dp,0,sizeof(dp));
        for(int i=s.size()-1;i>=0;i--)
        {
            for(int j=i+1;j<s.size();j++)
            {
                if(s[i]==s[j])
                    dp[i][j]=dp[i+1][j-1];
                else
                    dp[i][j]=min3(dp[i+1][j],dp[i][j-1],dp[i+1][j-1])+1;
            }
        }
        cout<<"Case "<<k<<": "<<dp[0][s.size()-1]<<endl;
    }
//  input.close();
//  output.close();
    return 0;
}

解答:
首先要能想到这是一个区间的动态规划问题,单纯考虑一个方向进行最优解是考虑不出来的。现在考虑两个方向,即设置dp[i][j]表示i到j这部分字符串所形成的回文需要多少步最少的操作。
接下来考虑状态转移,题目中给出的状态转移有3种方式,增加,替换,删除。其中增加和删除的效果是一样的,而且每次增加或者删除目的都是为了形成一个回文串,例如在字符串si….sj中,dp[i][j] =dp[i][j-1]+1可以表示为把第j个删除,也可以表示为在i前面加上一个字符(注意此时的si变成si+1)。如果是替换就是强行让第i个字符和第j个字符相同,也就是dp[i][j]=dp[i+1][j-1]+1。 所以转移方程就会是dp[i][j]=min(dp[i+1][j],dp[i][j-1],dp[i+1][j-1])+1(当s[i]!=s[j])时。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值