和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的复杂度,等以后遇到了再补吧。