hiho 1323 : 回文字符串 dp

#1323 : 回文字符串

时间限制:10000ms
单点时限:1000ms
内存限制:256MB

描述

给定一个字符串 S ,最少需要几次增删改操作可以把 S 变成一个回文字符串?

一次操作可以在任意位置插入一个字符,或者删除任意一个字符,或者把任意一个字符修改成任意其他字符。

输入

字符串 SS 的长度不超过100, 只包含'A'-'Z'。

输出

最少的修改次数。

样例输入
ABAD
样例输出
1
思路:经典动态规划题目。 
假设f(s[1..n])表示把长度为n的字符串s改写成回文串需要的操作。 
如果s[1] == s[n],那么f(s[1..n]) = f(s[2..n-1])。 
否则f(s[1..n])是以下三种情况的最小值: 
1. 在s[n]后添加一个字符匹配s[1],f(s[1..n]) = 1 + f(s[2..n])。 
2. 在s[1]前添加一个字符匹配s[n], f(s[1..n]) = 1 + f(s[1..n-1])。 
3. 把s[1]和s[n]其中一个修改为另外一个使其匹配,f(s[1..n]) = 1 + f(s[2..n-1])。
需要记忆话,不然超时
#include<bits/stdc++.h>
using namespace std;
#define ll long long
#define mod 1000000007
#define pi (4*atan(1.0))
const int N=1e3+10,M=1e6+10,inf=1e9+10;
char a[N];
int ans[N][N],x;
int dp(char *a,int len,int beg)
{
    if(len<=0)
    return 0;
    if(ans[beg][len])
    return ans[beg][len];
    if(a[0]==a[len-1])
    return ans[beg][len]=dp(a+1,len-2,beg+1);
    else
    {
        int ans1=dp(a,len-1,beg)+1;
        int ans2=dp(a+1,len-1,beg+1)+1;
        int ans3=dp(a+1,len-2,beg+1)+1;
        return ans[beg][len]=min(min(ans1,ans2),ans3);
    }
}
int main()
{
    int y,z,i,t;
    scanf("%s",a+1);
    x=strlen(a+1);
    dp(a+1,x,1);
    printf("%d
",ans[1][x]);
    return 0;
}
原文地址:https://www.cnblogs.com/jhz033/p/5603271.html