首页 > 其他 > 详细

poj 1159 Palindrome (LCS)

时间:2014-08-15 18:02:39      阅读:394      评论:0      收藏:0      [点我收藏+]

链接:poj 1159

题意:给定一个字符串,求最少添加多少个字符可使得该字符串变为回文字符串

分析设原序列S的逆序列为S‘ ,最少需要补充的字母数 = 原序列S的长度 - S和S‘的最长公共子串长度

原因要求最少添加几个字符,我们可以先从原串中找到一个最长回文串,然后对于原串中不属于这个回文串的字符,在它关于回文串中心的对称位置添加一个相同字符即可。那么需要添加的字符数量即为n-最长回文串长度。

最长回文串可以看作是原串中前面和后面字符的一种匹配(每个后面的字符在前面找到一个符合位置要求的与它相同的字符)。这种的回文匹配和原串与逆序串的公共子序列是一一对应的(一个回文匹配对应一个公共子序列,反之亦然),而且两者所涉及到的原串中的字符数量是相等的,也就是最长公共子序列对应最长回文串


注意:这题用 如果用静态数组 5001*5001 会内存超限,我用的 short 过了,不过可以用滚动数组

#include<stdio.h>
short dp[5005][5005];
int max(int a,int b)
{
    return a>b?a:b;
}
int main()
{
    int n,i,j;
    char s[5005],t[5005];
    while(scanf("%d",&n)!=EOF){
        getchar();
        for(i=0;i<n;i++){
            s[i]=getchar();
            t[n-i-1]=s[i];  //求逆序
            dp[i][0]=dp[0][i]=0;    //初始化
        }
        s[n]=t[n]=0;      
        for(i=0;i<n;i++)                //求原序与逆序的最长公共子串
            for(j=0;j<n;j++){
                if(s[i]==t[j])
                    dp[i+1][j+1]=dp[i][j]+1;
                else
                    dp[i+1][j+1]=max(dp[i][j+1],dp[i+1][j]);
            }
        printf("%d\n",n-dp[n][n]);
    }
    return 0;
}


poj 1159 Palindrome (LCS),布布扣,bubuko.com

poj 1159 Palindrome (LCS)

原文:http://blog.csdn.net/acm_code/article/details/38586411

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!