一:题目
二:上码
class Solution {
public:
/**
思路:
1.分析题意 这个是让我们求最值,那么首先想到动态规划
2.动态规划
1>:确定dp数组以及下标的含义
dp[i][j] 表示字符串在[i,j]范围内的最长回文子序列
2>:确定dp数组的状态递推公式
那么就是s[i] 与 s[j] 相等 不相等两种情况
s[i] != s[j]
s[i] = a 左边第一个字符
s[j] = c 最后一个字符
a b a a b c
当其不相等的时候 我们可以选择加入其中一个
加入s[j] dp[i][j] = dp[i+1][j] b a a b c
加入s[i] dp[i][j] = dp[i][j-1] a b a a b
那我们就选其中的最大值
dp[i][j] = max(dp[i+1][j],dp[i][j-1])
s[i] == s[j]
dp[i][j] = dp[i+1][j-1] + 2;
dp[i][j]表示的是在[i,j]范围内的最长的字符串
那么当s[i] == s[j]的话, 在字符范围的 i+1 和 j-1 的范围内最长的回文子序列肯定要+2
3>:确定dp数组的初始化
当一个字符的时候 我们将其dp[i][j] 初始化为 1
因为当dp[i][j] = dp[i-1][j+1] 我们是统计不到的
初始化为0 因为不可能一开始就是相等的
4>:确定dp数组的遍历顺序
根据状态递推公式 从下往上 从左往右
5>:举例验证
b b b a b
b 1 2 3 3 4
b 1 2 2 3
b 1 1 2
a 1 1
b 1
*/
int longestPalindromeSubseq(string s) {
vector<vector<int> >dp(s.size(),vector<int>(s.size(),0));
for(int i = 0; i < s.size(); i++) dp[i][i] = 1;
for (int i = s.size()-1; i >= 0; i--) {
for (int j = i + 1; j < s.size(); j++) {//这里从i+1开始 是因为我们的45度斜线已经都赋值为1了
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]);
}
}
return dp[0][s.size()-1];
}
};