题意:题意:有三种操作,添加任何字符到任何位置,移动任何字符到任何位置,替换任何字符。然后给你一个串,问你经过多少个操作,能使它变成一个回文子串。
状态定义dp(i,j)为字符串从i到j需要经过多少次操作才能变成一个回文子串。
如果str[i]!=str[j],那么可以选择的操作是删除或增加dp(i+1,j)+1或dp(i,j-1)+1,替换dp(i+1,j-1)+1。如果str[i]==str[j],那么就转移成dp(i+1,j-1)。
#include <iostream> #include <cstdio> #include <cstring> using namespace std; const int N=1005; char str[N]; int map[N][N],dp(int,int); bool vis[N][N]; int main() { int n,t_cnt=0; scanf("%d",&n); getchar(); while(n--) { gets(str); memset(vis,0,sizeof(vis)); memset(map,0,sizeof(map)); int len=strlen(str); printf("Case %d: %d\n",++t_cnt,dp(0,len-1)); } return 0; } int dp(int be,int end) { if(vis[be][end]) return map[be][end]; else if(be>=end) {vis[be][end]=1;map[be][end]=0;return 0;} else { int imin=1<<30; if(str[be]!=str[end]) imin=min(dp(be+1,end-1)+1,min(dp(be+1,end)+1,dp(be,end-1)+1)); else imin=dp(be+1,end-1); vis[be][end]=1; map[be][end]=imin; return imin; } }