UVA10739

 1 /* 
 2 
 3 题意: T组测试用例,每例不超过1000小写字母,
 4  三种操作把它变成回文,
 5  1.任意位置删除一个
 6  2.任意位置添加一个
 7  3.任意位置替换一个
 8  输出最小操作数 。
 9  
10  定义 dp[l][r] 为 l 到 r 要多少次操作,因为添加和删除效果一样,就只用删除和替换。
11  如果str[l]==str[r] 那么 dp[l][r]=dfs(l+1,r-1);
12  否则  dp[l][r]=min (dfs(l+1,r),dfs(l,r+1),dfs(l+1,r-1) );
13  这也是看了其他大神的做法后才造的,再接再厉,争取自己想到  o(╯□╰)o 
14   
15 */
16 #include<cstdio>
17 #include<algorithm>
18 #include<cstring>
19 using namespace std;
20 int dp[1010][1010];
21 char str[1010];
22 int dfs(int l,int r)
23 {
24     if(dp[l][r]!=-1) return dp[l][r];
25     if(l==r || l==r+1) return dp[l][r]=0; 
26     if(str[l]==str[r]) dp[l][r]=dfs(l+1,r-1); 
27     else
28     {
29         dp[l][r]=dfs(l+1,r);
30         int x=dfs(l,r-1);
31         dp[l][r]=(dp[l][r]<x)?dp[l][r]:x;
32         x=dfs(l+1,r-1);
33         dp[l][r]=(dp[l][r]<x)?dp[l][r]:x;
34         dp[l][r]+=1;
35     }
36     return dp[l][r];
37 }
38 int main()
39 {
40     int t,cnt=0;
41     scanf("%d",&t);
42     getchar();
43     while(t--)
44     {
45         scanf("%s",str);
46         memset(dp,-1,sizeof(dp));
47         int len=strlen(str);
48         printf("Case %d: %d
",++cnt,dfs(0,len-1));
49     }
50 }

 = =| N久之后再写......

#include <bits/stdc++.h>
#define ll long long
using namespace std;

const int maxn = 1010;
const int INF = 0x3f3f3f3f;

int d[maxn][maxn];
char s[maxn];

int dfs(int l, int r)
{
    if (d[l][r] != -1) return d[l][r];
    if (l >= r) return d[l][r] = 0;
    if(s[l] == s[r]) d[l][r] = dfs (l+1, r-1);
    else {
        d[l][r] =  dfs (l+1, r);
        d[l][r] = min (d[l][r], dfs (l, r-1));
        d[l][r] = min (d[l][r], dfs (l+1, r-1));
        d[l][r] += 1;
    }
    return d[l][r];
}

int main()
{
    int t, cas = 1;
    scanf ("%d", &t);
    getchar();
    while (t --) {
        scanf ("%s", s);
        memset (d, -1, sizeof (d));
        int r = strlen (s);
        int ans = dfs (0,r-1);
        printf ("Case %d: %d
", cas++, ans);
    }
    return 0;
}
原文地址:https://www.cnblogs.com/ember/p/4886412.html