Palindromic Subsequence
Palindromic Subsequence |
A Subsequence is a sequence obtained by deleting zero or more characters in a string. A Palindrome is a string which when read from left to right, reads same as when read from right to left. Given a string, find the longest palindromic subsequence. If there are many answers to it, print the one that comes lexicographically earliest.
Constraints
- Maximum length of string is 1000.
- Each string has characters `a' to `z' only.
Input
Input consists of several strings, each in a separate line. Input is terminated by EOF.
Output
For each line in the input, print the output in a single line.
Sample Input
aabbaabb computer abzla samhita
Sample Output
aabbaa c aba aha
题意:
给定一个字符串,要求你删除尽量少的字符,使得原字符串变为最长回文串,并把回文串输出,如果答案有多种,则输出字典序最小的。
思路:
dp[i][j]表示i~j得到的最大回文串,
if(s[i]==s[j]) dp[i][j]=dp[i+1][j-1]+2;
else dp[i][j]=max(dp[i+1][j],dp[i][j-1]);
这样能得到最大的长度,记录路径后能得到一组解,但是不能得到字典序最小的解。(谈到字典序就要想到求出的是否是最小字典序)
因为在dp[i+1][j]=dp[i][j-1]的时候而且开头字母相同的时候不知道怎样选取,如pkgoxdyddjau。
所以只能用string来记录路径了。
也可以把字符串逆序,然后求两个字符串的LCS,并记录LCS,长度就等于最长回文串的长度,不过求出来的LCS不一定是回文串,如1 5 2 4 3 3 2 4 5 1,只需要知道前半段就行,后半段构造。
代码:(方法一)
#include <iostream>
#include <cstdio>
#include <cstring>
#include <algorithm>
#include <cmath>
#include <string>
#include <map>
#include <stack>
#include <vector>
#include <set>
#include <queue>
#define maxn 1005
#define MAXN 100005
#define mod 100000000
#define INF 0x3f3f3f3f
#define pi acos(-1.0)
#define eps 1e-6
typedef long long ll;
using namespace std;
int n,m,ans,cnt,tot,k;
char s[maxn];
int dp[maxn][maxn];
string ds[maxn][maxn];
int main()
{
int i,j,t;
// freopen("out.txt","w",stdout);
while(gets(s+1)!=NULL)
{
n=strlen(s+1);
if(n==0)
{
printf("\n");
continue ;
}
memset(dp,0,sizeof(dp));
for(i=1;i<=n;i++)
{
dp[i][i]=1;
ds[i][i]=s[i];
}
for(int len=2;len<=n;len++)
{
for(i=1;i<=n;i++)
{
j=i+len-1;
if(j>n) break ;
if(s[i]==s[j])
{
dp[i][j]=dp[i+1][j-1]+2;
ds[i][j]=s[i]+ds[i+1][j-1]+s[j];
}
else
{
if(dp[i+1][j]>dp[i][j-1])
{
dp[i][j]=dp[i+1][j];
ds[i][j]=ds[i+1][j];
}
else if(dp[i+1][j]<dp[i][j-1])
{
dp[i][j]=dp[i][j-1];
ds[i][j]=ds[i][j-1];
}
else
{
dp[i][j]=dp[i+1][j];
if(ds[i+1][j]<ds[i][j-1]) ds[i][j]=ds[i+1][j];
else ds[i][j]=ds[i][j-1];
}
}
}
}
// printf("%d\n",dp[1][n]);
cout<<ds[1][n]<<endl;
}
return 0;
}
/*
bxxzxcsdgvsgaxxk
xxzxaxx
bxxzxcaxxxbk
b
aabbaabb
computer
abzla
samhita
xcvabxcy
baba
pkgoxdyddjau
*/