📝

Leetcode 3474

Importance
📙📙📙
Start Date
Mar 2, 2025 14:21
tags
Dynamic Programming
String

题目要求

给你一个字符串 s 和一个整数 k
在一次操作中,你可以将任意位置的字符替换为字母表中相邻的字符(字母表是循环的,即 'z' 的下一个字母是 'a')。
返回在进行 最多 k 次操作后,s 的 最长回文子序列 的长度。
 

核心算法和原理

  • 区间DP,dp[m][i][j] 表示 在操作次数至多为m的情况下,s[i..j]的最长回文子序列长度
  • 选或不选(是否将s[i]或s[j]加入 回文的子序列中):
    • 不选s[i]或s[j]则为 dp[m][i + 1][j] or dp[m][i][j - 1]
    • 选:设最优地进行op次操作后s[i] = s[j],res = | s[i] - s[j] |,op = min(res, 26 - res),则为dp[m - op][i + 1][j - 1]
 

代码

class Solution { public: int longestPalindromicSubsequence(string s, int k) { int n = s.size(); vector dp(k + 1, vector(n, vector<int>(n))); for (int m = 0; m <= k; m++) { for (int i = n - 1; i >= 0; i--) { dp[m][i][i] = 1; for (int j = i + 1; j < n; j++) { int dif = abs(s[i] - s[j]); int op = min(dif, 26 - dif); dp[m][i][j] = max(dp[m][i + 1][j], dp[m][i][j - 1]); if (m - op >= 0) { dp[m][i][j] = max(dp[m][i][j], dp[m - op][i + 1][j - 1] + 2); } } } } return dp[k][0][n - 1]; } };