题解 CF1446B 【Catching Cheaters】
解析
直接魔改下
具体来说,设
转移时也和公共子序列一样,考虑匹配
还有不理解的地方可参考代码
CODE
#include <cstdio>
#include <iostream>
using std::max;
const int MAXN =5050;
int dp[MAXN][MAXN];/*C 为 0..A_{i-1} 后缀,D 为 0..B_{j-1} 后缀,的最大贡献*/
char s1[MAXN], s2[MAXN];
int main(){
int n, m;
scanf("%d%d", &n, &m);
scanf("%s%s", s1, s2);
int ans =0;/*初值注意下 C, D 均空也是一种答案*/
for(int i =1; i <= n; ++i)
dp[i][0] =-i;
for(int j =1; j <= m; ++j)
dp[0][j] =-j;
for(int i =1; i <= n; ++i)
for(int j =1; j <= m; ++j){
if(s1[i-1] == s2[j-1]){/*尝试匹配 i, j*/
int tmp1 =dp[i-1][j-1]+4*1-2,
tmp2 =4*1-2;
dp[i][j] =max(tmp1, tmp2);
}
else{
int tmp1 =dp[i-1][j-1]-2,
tmp2 =-2;
dp[i][j] =max(tmp1, tmp2);
}
int tmp01 =dp[i-1][j]-1,/*不尝试匹配 i, j*/
tmp02 =dp[i][j-1]-1;
dp[i][j] =max(dp[i][j], max(tmp01, tmp02));
ans =max(ans, dp[i][j]);
}
printf("%d", ans);
}