这个题目是编辑距离的变形
思路就是枚举每个字符串的点,这个点要么成为回文串的对称点(回文串长度为奇数的时候), 要么不成为对称点(回文串为偶数的时候),然后就是应用编辑距离的模板
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
#define MAXN 1001
#define INF 0x3f3f3f3f
int dp[MAXN][MAXN];
char str[MAXN], stra[MAXN], strb[MAXN];
void split_str(const int &mid_idx, const int &mark)
{
int len(strlen(str)), idx(0), final( (mark)? mid_idx+1 : mid_idx);
for(int i = 0; i < mid_idx; i ++, idx ++) {
stra[idx] = str[i];
}
stra[idx] = '\0'; idx = 0;
for(int i = len-1; i >= final; i --, idx ++) {
strb[idx] = str[i];
}
strb[idx] = '\0';
}
int dynamic_pro(void)
{
int lena(strlen(stra)), lenb(strlen(strb));
for(int i = 0; i <= lena; i ++) {
dp[i][0] = i;
}
for(int i = 0; i <= lenb; i ++) {
dp[0][i] = i;
}
for(int i = 1; i <= lena; i ++) {
for(int j = 1; j <= lenb; j ++) {
if( stra[i-1] == strb[j-1] ) {
dp[i][j] = dp[i-1][j-1]; continue;
}
dp[i][j] = min(dp[i][j-1]+1, min(dp[i-1][j-1]+1, dp[i-1][j]+1));
}
}
return dp[lena][lenb];
}
int main(int argc, char const *argv[])
{
#ifndef ONLINE_JUDGE
freopen("test.in", "r", stdin);
#endif
int n, cas(1), rst, start, final;
scanf("%d", &n);
for( ; n; n --) {
scanf("%s", str); rst = INF;
start = strlen(str)/2-10; final = (strlen(str)/2+10); //确定这个范围郁闷,其实不确定,uva 都可以过,只不过是使用0.8s
for(int i = start; i <= final; i ++) {
if( i < 0 || i >= strlen(str) ) {
continue;
}
split_str(i, 0); rst = min(rst, dynamic_pro());
split_str(i, 1); rst = min(rst, dynamic_pro());
}
printf("Case %d: %d\n", cas ++, (INF == rst)? 0 : rst);
}
return 0;
}