cf1446 B. Catching Cheaters(dp)
题意:
给定两个字符串 a 和 b ,找 a 的子串 C 和 b 的子串 D,最大化 \(4\cdot LCS(C,D)-|C|-|D|\) 。其中 LCS为最长公共子序列 (subsequence) 的长度。
子串 - substring - 连续
子序列 - subsequence - 不要求连续
这俩都可以是空串
思路:
\(f(i,j)\) 表示 \(C\) 以 \(a_i\) 结尾,\(D\) 以 \(b_j\) 结尾时的最大答案。
首先,如果所有子串的长度都为1,位置上相等就是2,不等就是0(取两个空串)。所以 \(f\) 不小于0或2
若 \(a_i=a_j\) ,则应该扩展 LCS,\(f(i,j)=f(i-1,j-1)+4-1-1\)
而无论是否相等,都能 \(f(i,j)=max\{f(i-1,j),f(i,j-1)\}-1\) (不扩展LCS)
#include <bits/stdc++.h>
using namespace std;
const int N = 5005;
int n, m, f[N][N];
char a[N], b[N];
signed main()
{
scanf("%d%d", &n, &m); scanf("%s%s", a+1, b+1);
int ans = 0;
for(int i = 1; i <= n; i++)
for(int j = 1; j <= m; j++)
{
if(a[i] == b[j]) f[i][j] = max(2, f[i-1][j-1] + 2);
else f[i][j] = max(0, max(f[i-1][j], f[i][j-1])-1);
ans = max(ans, f[i][j]);
}
printf("%d", ans);
return 0;
}