由于添加字母和删除字母的效果是一样的,因此我们这里就只进行删除和替换操作。
用f【i】【j】表示将第i到j之间的字串变成回文串的最小操作步数,然后转移方程为当s【i】!=s【j】时,f【i】【j】 = min( f【i+1】【j】 ,f【i】【j-1】,f【i+1】【j-1】)+1;当相等时f【i】【j】 =f【i+1】【j-1】;递归操作更方便;
#include<stdio.h> #include<string.h> #define MAXN 1010 #define INF 0x7fffffff char s[MAXN]; int n, f[MAXN][MAXN]; int dp(int x, int y) { int t, min = INF; if(f[x][y] != -1) return f[x][y]; if(x > y) return 0; if(s[x] == s[y]) { t = dp(x+1,y-1); if(t < min) min = t; } else { t = dp(x+1, y); if(t+1 < min) min = t +1; t = dp(x, y - 1); if(t+1 < min) min = t +1; t = dp(x+1, y - 1); if(t+1<min) min = t + 1; } return f[x][y] = min; } void input() { while(scanf("%d", &n) == 1) { int num = 0; while(n --) { scanf("%s",s); printf("Case %d: ",++num); int len = strlen(s); memset(f,-1,sizeof(f)); printf("%d\n",dp(0,len-1)); } } } int main() { input(); return 0; }