题目大意:给一个字符串,可以对该字符串进行增,删,替换三种操作,求用最少的操作让字符串变成回文串

解题思路:又是字符串的回文问题,想了很久,思来想去怎么替换,怎么删除,怎么增加,结果想偏了,他只是问最少操作数,而不是要你修改。。。添加和删除这两个操作相对说是等价的,这样只需要考虑添加和替换两个操作了,这样问题就转换了,设dp[i][j]表示第i个字符串到第j个字符串变成回文字符串的最少操作,则

1.如果str[i] == str[j],则dp[i][j] = dp[i+1][j-1]

2.如果str[i] != str[j],则dp[i][j] = min(dp[i+1][j],dp[i][j-1],dp[i+1][j-1]) + 1,dp[i+1][j-1]是替换的,其余两个是添加的,dp[i+1][j]是在j后面添加str[i],dp[i][j-1]是在i的前面添加str[j]

#include<cstdio>
#include<algorithm>
#include<cstring>
using namespace std;
#define maxn 1005
#define INF 0x3f3f3f3f
char str[maxn];
int dp[maxn][maxn];
int DP(int i, int j) {

	if(dp[i][j] != -1)
		return dp[i][j];
	if(i == j || i == j + 1)
		return dp[i][j] = 0;
	if(str[i] == str[j])
		dp[i][j] = DP(i+1,j-1);
	else {
		dp[i][j] = DP(i+1,j);
		if(DP(i+1,j-1) < dp[i][j])
			dp[i][j] = DP(i+1,j-1);
		if(DP(i,j-1) < dp[i][j])
			dp[i][j] = DP(i,j-1);
		dp[i][j] += 1;
	}
	return dp[i][j];
}
int main() {
	int test;	
	scanf("%d\n",&test);
	int mark = 1;
	while(test--) {	
		gets(str);
		int len = strlen(str);
		memset(dp,-1,sizeof(dp));

		printf("Case %d: %d\n",mark++,DP(0,len-1));
	}
	return 0;
}