UVA10739 String to Palindrome(区间DP + 递推)

来源:互联网 发布:手机换网络类型软件 编辑:程序博客网 时间:2024/04/29 15:22
Sample Input6tanbirahmedshahriarmanzoormonirulhasansyedmonowarhossainsadrulhabibchowdhurymohammadsajjadhossainSample OutputCase 1: 5Case 2: 7Case 3: 6Case 4: 8Case 5: 8Case 6: 8题意:给出一个字符串,可以添加删除字符,或替换字符,求把它变成回文的最少操作次数。dp[i][j]表示字符i到j位置上最少需要几步构成回文。分两种情况讨论: 1.str[i] == str[j],此时则直接用上一步的值进行更新这一步,即dp[i][j] = dp[i+1][j-1]2.str[i]!=str[j],此时可以有两种操作,替换,删除,状态转移方程为dp[i][j] = min(min(dp(i+1,j),dp(i,j-1),dp(i+1,j-1))动规#include <iostream>#include <algorithm>#include <stdio.h>#include <string.h>const int INF = 0x3f3f3f3f;using namespace std;int dp[1010][1010];int n,len;char str[1010];int main(){    int Case = 0;    scanf("%d",&n);    while(n --)    {        scanf("%s",str);        len = strlen(str) - 1;        memset(dp,0,sizeof(dp));        for(int i = len; i >= 0; i --)            for(int j = i + 1; j <= len; j ++)                if(str[i] == str[j])                    dp[i][j] = dp[i+1][j-1];                else                    dp[i][j] = min(min(dp[i+1][j],dp[i][j-1]),dp[i+1][j-1]) + 1;        printf("Case %d: %d\n",++ Case,dp[0][len]);    }    return 0;}记忆化搜索#include <iostream>#include <algorithm>#include <stdio.h>#include <string.h>const int INF = 0x3f3f3f3f;using namespace std;int dp[1010][1010];int n,len;char str[1010];int DFS(int x,int y){    if(x <= y)  ///结束条件    {        if(x == y || (x + 1 == y && str[x] == str[y]))        {            dp[x][y] = 0;            return dp[x][y];        }        if(dp[x][y] != INF) ///减枝            return dp[x][y];        if(str[x] == str[y])            dp[x][y] = min(dp[x][y],DFS(x + 1,y - 1));        else        {            if(DFS(x + 1,y) < dp[x][y])                dp[x][y] = DFS(x + 1,y);            if(DFS(x,y - 1) < dp[x][y])                dp[x][y] = DFS(x,y-1);            if(DFS(x + 1,y - 1) < dp[x][y])                dp[x][y] = DFS(x + 1,y - 1);            dp[x][y] += 1;        }        return dp[x][y];    }    return INF;}int main(){    int Case = 0;    scanf("%d",&n);    while(n --)    {        scanf("%s",str);        len = strlen(str);        memset(dp,INF,sizeof(dp));        printf("Case %d: %d\n",++ Case,DFS(0,len-1));    }    return 0;}</span>

0 0