标签:子串 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; }
标签:子串 size 潜规则 ring max 递推 eve pac 反转
原文地址:http://www.cnblogs.com/G-M-WuJieMatrix/p/7351393.html