题目地址:http://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&page=show_problem&problem=2399
题目意思:
给你一个字符串,问你其中能组成的最长回文串,输出字典序最小的
解题思路:
将串倒置和原串求LCS,然后取前len/2作为回文串的前半部
然后倒过来做后半部,注意长度的奇偶问题
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<string>
using namespace std;
const int maxn = 1010;
int len[maxn][maxn];
string s[maxn][maxn];
char s1[maxn],s2[maxn];
int main()
{
while(~scanf("%s",&s1[1]))
{
int l = strlen(s1+1);
for(int i=1;i<=l;i++)
s2[i] = s1[l-i+1];
for(int i=0;i<=l;i++)
{
len[0][i] = len[i][0] = 0;
s[0][i] = s[i][0] = "";
}
for(int i=1;i<=l;i++)
{
for(int j=1;j<=l;j++)
{
if(s1[i] == s2[j])
{
len[i][j] = len[i-1][j-1]+1;
s[i][j] = s[i-1][j-1]+s1[i];
}
else
{
if(len[i-1][j] > len[i][j-1])
{
len[i][j] = len[i-1][j];
s[i][j] = s[i-1][j];
}
else if(len[i-1][j] < len[i][j-1])
{
len[i][j] = len[i][j-1];
s[i][j] = s[i][j-1];
}
else
{
len[i][j] = len[i-1][j];
s[i][j] = min(s[i-1][j],s[i][j-1]);
}
}
}
}
int anslen = len[l][l];
string ans = s[l][l];
if(anslen & 1)
{
for(int i=0;i<anslen/2;i++)
{
printf("%c",ans[i]);
}
for(int i=anslen/2;i>=0;i--)
{
printf("%c",ans[i]);
}
}
else
{
for(int i=0;i<anslen/2;i++)
{
printf("%c",ans[i]);
}
for(int i=anslen/2-1;i>=0;i--)
{
printf("%c",ans[i]);
}
}
printf("\n");
}
return 0;
}