记忆化搜索。
dp[i][j]表示区间[【i,j】之间插入个数。
if str[i]==str[j] dp[i][j]=dp[i+1][j-1]
else dp[i][j]=min(dp[i+1][j],dp[i][j-1])+1
同时记录转移 递归输出
不知道怎么搞的,跑了2.5s。。
#include <iostream> #include <cstdlib> #include <cstdio> #include <cstring> #include <algorithm> #define MAXN 1005 #define INF 2139062143 using namespace std; int dp[MAXN][MAXN]; int shift[MAXN][MAXN]; char str[MAXN]; int L; int solve(int x,int y) { if(x<=y) { if(dp[x][y]!=INF) return dp[x][y]; if(x==y||(x+1==y&&str[x]==str[y])) return dp[x][y]=0; if(str[x]==str[y]) { dp[x][y]=min(dp[x][y],solve(x+1,y-1)); shift[x][y]=0; } else { int l=solve(x,y-1),r=solve(x+1,y); if(l<r) { dp[x][y]=min(dp[x][y],l+1); shift[x][y]=-1; } else { dp[x][y]=min(dp[x][y],r+1); shift[x][y]=1; } } return dp[x][y]; } return INF; } void Out_put(int x,int y) { if(x<=y) { if(x==y) putchar(str[x]); else { if(shift[x][y]==0) { putchar(str[x]); Out_put(x+1,y-1); putchar(str[y]); } else if(shift[x][y]==-1) { putchar(str[y]); Out_put(x,y-1); putchar(str[y]); } else if(shift[x][y]==1) { putchar(str[x]); Out_put(x+1,y); putchar(str[x]); } } } } int main() { while(scanf("%s",str)!=EOF) { memset(dp,0x7f,sizeof(dp)); memset(shift,0,sizeof(shift)); L=strlen(str); printf("%d ",solve(0,L-1)); Out_put(0,L-1); printf("\n"); } return 0; }