UVa:10453 Make Palindrome

来源:互联网 发布:网络电话卡哪里有卖 编辑:程序博客网 时间:2024/06/04 19:46

记忆化搜索。

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 2139062143using 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;}


 

 

 

0 0
原创粉丝点击