至多K次操作后的最长回文子序列
题目大意
在一次操作中,你可以将任意位置的字符替换为字母表中相邻的字符,返回在进行最多k次操作后,s 的最长回文子序列的长度。
思路
使用了区间dp的思想,开三维数组,一个记录k的情况,还有两个记录数组的起始与终止位置。
与经典背包问题类似,主要思想在于是否要对当前节点进行变化。
如何统一变化后的代价表示?
d=abs(s[i]-s[j]),op=min(d,26-d);将数据一直保持在合法范围内;
状态转移方程
当可选择变化该节点时:
f[pk][i][j]=max({f[pk][i+1][j],f[pk][i][j-1],f[pk-op][i+1][j-1]+2});
当该节点不可变化时:
f[pk][i][j]=max(f[pk][i+1][j],f[pk][i][j-1]);
代码
点击查看代码
class Solution {
public:
int longestPalindromicSubsequence(string s, int k) {
int n=s.size();
vector f(k+1,vector(n,vector<int>(n)));
for(int pk=0;pk<=k;pk++){
for(int i=n-1;i>=0;i--){
f[pk][i][i]=1;
for(int j=i+1;j<n;j++){
int ans=max(f[pk][i+1][j],f[pk][i][j-1]);
int d=abs(s[i]-s[j]);
int op=min(d,26-d);
if(op<=pk){
ans=max(ans,f[pk-op][i+1][j-1]+2);
}
f[pk][i][j]=ans;
}
}
}
return f[k][0][n-1];
}
};

浙公网安备 33010602011771号