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;
}
posted @ 2021-12-18 12:01  Bellala  阅读(34)  评论(0)    收藏  举报