和lcs差不多,也可以用递归来写,但是会重复处理很多次,所以还是考虑用动态规划来写。它的动态转移方程为
当str[i]==str[j]时,i->j的最长回文子序列就等于,在 i->j 之间上一个最长回文子序列的基础上+2
当str[i]!=str[j]时,i->j的最长回文子序列就等于在i+1->j 和 i->j-1中最长回文子序列较长的一个
最终的dp[0][len-1]就是最长回文子序列。
实现代码:
#include <iostream>
#include <cstdio>
#include <cstring>
#define Max(a,b) a>b?a:b
using namespace std;
int dp[1500][1500];
int main()
{
string str;
while(cin>>str){
int len = str.length();
memset(dp,0,sizeof(dp));
for(int i=len-1;i>=0;i--){
dp[i][i] = 1;
for(int j=i+1;j<len;j++){
if(str[i] == str[j])dp[i][j] = dp[i+1][j-1] + 2;
else dp[i][j] = Max(dp[i][j-1],dp[i+1][j]);
}
}
printf("%d\n",dp[0][len-1]);
}
return 0;
}
这个是n^2的时间复杂度,空间也是n^2的,还有一种空间优化的空间为n的复杂度,等以后遇到了再补吧。