- 问题描述
-
给定一组字符串长度不大于1000,字符范围a~z。
从这个字符串中取出K个字符,在这些字符相对位置不变的情况下能够组成一个回文串,求K的最大值。
例如,对于字符串:abcda。
我取k=3,我可以取abcda中的第一个第三个第五个字符组成新的字符串aca,他是一个回文串。
所谓回文串,就是这个字符串是根据中心点成对称的。
- 输入
-
输入有多次,每次输入一个字符串s(strlen(s) <= 1000)。
- 输出
-
输出在相对位置不变的情况下能够组成回文串的最大字符数量K(即所组成的回文串的长度)。
- 样例输入
-
a abcda ababaa
- 样例输出
-
1 3 5
- 提示
-
无
- 来源
-
[ecjtu]xyyh
题意是要从给的字符串中找到一个最长的回文串,那么就和删除最少的字符形成回文串一样,所以我们只要求给定的字符串和他的逆序字符串的最长公共子序列就行了,原理的话,一个回文串,正读反读都一样,那么一定是这两个字符串的公共子序列,换句话说,由于回文串的回文性质,倒过来以后,它的顺序实际没变,然原来那些其他的字符,倒过来就改变了顺序,所以不会出现在最长公共子序列里,那么我们求出来的最长公共子序列就是最长回文串了。
#include<stdio.h>
#include<string.h>
#include<algorithm>
#include<iostream>
#include<map>
#include<set>
#include<iterator>
#include<vector>
#include<queue>
using namespace std;
char str1[1010],str2[1010];
int dp[1010][1010];
int main()
{
int n;
while(~scanf("%s",str1))
{
int len=strlen(str1);
int i,j=0;
for(i=len-1;i>=0;i--)
str2[j++]=str1[i];
str2[j]='\0';
for(i=0;i<=len;i++)
{
dp[i][0]=0;
dp[0][i]=0;
}
for(int i=1;i<=len;i++)
for(int j=1;j<=len;j++)
{
if(str1[i-1] == str2[j-1])
dp[i][j]=dp[i-1][j-1]+1;
else if(dp[i][j-1] >= dp[i-1][j])
dp[i][j]=dp[i][j-1];
else
dp[i][j]=dp[i-1][j];
}
printf("%d\n",dp[len][len]);
}
return 0;
}