码迷,mamicode.com
首页 > 其他好文 > 详细

HDU 1513[Palindrome] 回文串

时间:2017-08-12 21:15:03      阅读:175      评论:0      收藏:0      [点我收藏+]

标签:子串   size   潜规则   ring   max   递推   eve   pac   反转   

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1513

题目大意:给一个字符串,问最少加多少个字母能成为回文串。

关键思想:要解决的是回文子序列问题而不是回文子串。回文子序列怎么求?可以把字符串倒转一下,再求他们的最长公共子序列啊!想一想为什么。求出LCS长度之后,n-LCS才是我们要的答案,因为对于不是回文子序列的其他字符来说,都需要给他们一个对象才能回文(对称)。还有一个问题是我们开不了5000*5000的数组,但观察到递推方程是只与两个状态有关,

i的n-1态和i的n态,而j的n-1态在遍历的时候可以得到。也就是说,我们只要2*5000就能达到要求了。这就是滚动数组,轮流成为现态。

代码如下:

#include <iostream>
#include <algorithm>
#include <string.h>
#include <string>
using namespace std;
const int MAXN=5050;

int c[2][MAXN];

int LCS(string a,string b){
    memset(c,0,sizeof(c));
    for(int i=1;i<=a.size();i++){
        for(int j=1;j<=b.size();j++){
            if(a[i-1]==b[j-1]){
                c[i&1][j]=c[1-i&1][j-1]+1;//如果是奇数用c[1],否则用c[2]    
            }
            else{
                c[i&1][j]=max(c[i&1][j-1],c[1-i&1][j]);    
            }
        }
    }
    return c[a.size()&1][b.size()];
    //注意下标,c[i][j]表示A[0,i-1]和B[0,j-1]的LCS长度 
}

int main(){
    int n;
    string a,ra;
    while(cin>>n>>a){//多组输入输出,潜规则 
        ra=a;
        reverse(ra.begin(),ra.end());//反转一下 
        cout<<n-LCS(a,ra)<<endl;//除了回文子序列,其他的都需要一个对象     
    }
    return 0;
}

 

HDU 1513[Palindrome] 回文串

标签:子串   size   潜规则   ring   max   递推   eve   pac   反转   

原文地址:http://www.cnblogs.com/G-M-WuJieMatrix/p/7351393.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!