题解
- dp[i][j]表示[i,j]最少要添加的字符的个数,使之成为回文串。
- 初始化dp[i][i] = 0
- if(s[i] == s[j]) dp[i][j] = dp[i+1][j-1] //不用添加任何字符
- else dp[i][j] = min(dp[i+1][j],dp[i][j-1]) + 1 //只用添加一个字符
- 比如有a***d,那么可以是***d变成回文子串,然后最右边加上a。或者a***变成回文子串,最左边加上d。取两者最小值
代码
#include <bits/stdc++.h>
using namespace std;
int const N = 100 + 10;
char s[N];
int dp[N][N];
int solve(){
memset(dp,0,sizeof(dp));
int len = strlen(s+1);
for(int i=len-1;i>=1;i--){
for(int j=i+1;j<=len;j++){
if(s[i] == s[j]) dp[i][j] = dp[i+1][j-1];
else dp[i][j] = min(dp[i+1][j],dp[i][j-1]) + 1;
}
}
return dp[1][len];
}
int main(){
int T;
scanf("%d",&T);
int caser = 0;
while(T--){
scanf(" %s",s+1);
printf("Case %d: %d\n",++caser,solve());
}
return 0;
}