题目链接:
本题考察区间 \(dp\)。
设 \(f[i][j]\) 表示子串 \(i \sim j\) 中的最长回文子序列的长度。
思考状态转移方程。因为是判断回文的问题,考虑首尾元素是否相同。
若首尾元素相同,则考虑去掉首尾元素之后子串的最长回文子序列的长度 + 2(首、尾元素各一个)
反之若首尾元素不相同,则分别去掉首和尾,看子串的最长回文子序列长度的最大值。
实现一、递推
class Solution {
public:
static const int N = 1010;
int f[N][N];
int longestPalindromeSubseq(string s) {
int n = s.size();
for (int i = n - 1; i >= 0; i--) {
f[i][i] = 1;//长度为1的子串
for (int j = i + 1; j < n; j++) {//长度不为1的子串
if (s[i] == s[j]) f[i][j] = f[i + 1][j - 1] + 2;
else f[i][j] = max(f[i + 1][j], f[i][j - 1]);
}
}
return f[0][n - 1];
}
};
实现二、记忆化搜索
class Solution {
public:
int longestPalindromeSubseq(string s) {
int n = s.size();
int memo[n][n];
memset(memo, -1, sizeof memo);//初始化为-1,表示没有计算过
function<int(int, int)> dfs = [&] (int i, int j) -> int {
if (i > j) return 0;//空串
if (i == j) return 1;//只有一个字母
int &res = memo[i][j];//引用,简化代码
if (res != -1) return res;
if (s[i] == s[j]) return res = dfs(i + 1, j - 1) + 2;
return res = max(dfs(i, j - 1), dfs(i + 1, j));
};
return dfs(0, n - 1);
}
};
标签:子串,return,int,res,dfs,序列,516,回文
From: https://www.cnblogs.com/pangyou3s/p/18125001