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])时。

你可能感兴趣的:(uva)