题意:给你一串字符串,使用最少的操作,使该字符串转变成回文字符串。有三种操作添加字母,删除字母,替换字母。
思路:其实删除和添加字母操作所产生的效果是一样的。因此实际上只有两种操作。d[i][j]表示的是从字符i到字符j变成回文的最小的操作数。
状态转移方程:
当str[i] == str[j],d[i][j] = d[i + 1][j - 1];
当str[i] != str[j],d[i][j] = min(d[i + 1][j], d[i][j - 1], d[i + 1][j - 1]) + 1;
#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
const int MAXN = 1005;
char str[MAXN];
int d[MAXN][MAXN];
int dp(int a, int b) {
if (a >= b)
return 0;
if (d[a][b] != -1)
return d[a][b];
if (str[a] == str[b])
d[a][b] = dp(a + 1, b - 1);
else
d[a][b] = min(min(dp(a + 1, b), dp(a, b - 1)), dp(a + 1, b - 1)) + 1;
return d[a][b];
}
int main() {
int cas, t = 1;
scanf("%d", &cas);
while (cas--) {
scanf("%s", str);
int len = strlen(str);
memset(d, -1, sizeof(d));
int ans = dp(0, len - 1);
printf("Case %d: %d\n", t++, ans);
}
return 0;
}