题意:给你一个字符串,要你删除一些字符让剩下的字符组成尽量长的回文串。
分析:将原串反转下,然后和原串求一边LCS,顺便把字典序最小的存下来,但是这个串并不一定是回文串,但是我们可以确定他的前一半一定是回文串的前半部分。
最后注意长度的奇偶。
代码:
#include<algorithm> #include<iostream> #include<cstring> #include<cstdio> #include<string> #include<vector> #include<queue> #include<cmath> #include<stack> #include<set> #include<map> #define INF 0x3f3f3f3f #define Mn 1010 #define Mm 2010 #define mod 1000000007 #define CLR(a,b) memset((a),(b),sizeof((a))) #define CPY(a,b) memcpy ((a), (b), sizeof((a))) #pragma comment(linker, "/STACK:102400000,102400000") #define ul u<<1 #define ur (u<<1)|1 using namespace std; typedef long long ll; string ss[Mn][Mn],s,p; int main() { while(cin>>s) { int len=s.size(); p=s; reverse(p.begin(),p.end()); s=" "+s; p=" "+p; for(int i=1; i<=len; i++) { for(int j=1; j<=len; j++) { if(s[i]==p[j]) { ss[i][j]=ss[i-1][j-1]+s[i]; //cout<<ss[i][j]<<endl; } else { if(ss[i-1][j].size()>ss[i][j-1].size()) ss[i][j]=ss[i-1][j]; else if(ss[i-1][j].size()==ss[i][j-1].size()) ss[i][j]=min(ss[i-1][j],ss[i][j-1]); else ss[i][j]=ss[i][j-1]; } } } string pp=ss[len][len]; //cout<<pp<<endl; len=pp.size(); if(len%2) { for(int i=0;i<len/2;i++) cout<<pp[i]; for(int i=len/2;i>=0;i--) cout<<pp[i]; } else { for(int i=0;i<len/2;i++) cout<<pp[i]; for(int i=len/2-1;i>=0;i--) cout<<pp[i]; } cout<<endl; } return 0; }