D. Catching Cheaters(动态规划)Codeforces Round #683 (Div. 2, by Meet IT)

原题链接; http://codeforces.com/contest/1447/problem/D

在这里插入图片描述
测试样例

input
4 5
abba
babab
output
5
input
8 10
bbbbabab
bbbabaaaaa
output
12
input
7 7
uiibwws
qhtkxcn
output
0

Note

For the first case:
abb from the first string and abab from the second string have LCS equal to abb.
The result is S(abb,abab)=(4⋅|abb|) - |abb| - |abab| = 4⋅3−3−4=5.

题意: 给你两个字符串 A , B A,B A,B。认定 S ( C , D ) = 4 ⋅ L C S ( C , D ) − ∣ C ∣ − ∣ D ∣ S(C,D)=4\cdot LCS(C,D) - |C| - |D| S(C,D)=4LCS(C,D)CD,其中 C C C A A A的子串, D D D B B B的子串。LCS代表的是求 C C C D D D的最长公共子序列。 ∣ ∣ || 代表求字符串的长度。现在你需要最大化 S ( C , D ) S(C,D) S(C,D)

解题思路: 最长公共子序列的变种题。如果我们了解过这阵求最长公共子序列的题,那么这个题就好办了,我们要清楚贡献, A [ i ] = B [ j ] A[i]=B[j] A[i]=B[j]。那么此刻我们如果都往后移的话那么总得分是加 2 2 2。而如果不相等大的话,那么我们这个状态是可以通过上一个状态转移过来的,即 d p [ i − 1 ] [ j ] , d p [ i ] [ j − 1 ] dp[i-1][j],dp[i][j-1] dp[i1][j],dp[i][j1],那么此时LCS没变,而长度增 1 1 1。故总得分减 1 1 1。其余的即是按动态规划求解最长公共子序列一样做,只不过这个题需要实时保存最大值。具体看代码。

AC代码

/*
*邮箱:unique_powerhouse@qq.com
*blog:https://me.csdn.net/hzf0701
*注:文章若有任何问题请私信我或评论区留言,谢谢支持。
*
*/
#include<bits/stdc++.h>//POJ不支持

#define rep(i,a,n) for(int i=a;i<=n;i++)
#define per(i,a,n) for(int i=a;i>=n;i--)

using namespace std;

const int inf=0x3f3f3f3f;//无穷大。
const int maxn=5500;//限定值。
typedef long long ll;

int n,m;
char a[maxn],b[maxn];
int dp[maxn][maxn];
int main(){
    while(cin>>n>>m){
        cin>>(a+1)>>(b+1);
        memset(dp,0,sizeof(dp));
        int maxx=0;
        rep(i,1,n){
            rep(j,1,m){
                if(a[i]==b[j]){
                    dp[i][j]=max(0,dp[i-1][j-1])+2;
                }
                else{
                    dp[i][j]=max(dp[i-1][j],dp[i][j-1])-1;
                }
                maxx=max(maxx,dp[i][j]);
            }
        }
        cout<<maxx<<endl;
    }
	return 0;
}
posted @ 2022-03-26 16:49  unique_pursuit  阅读(32)  评论(0)    收藏  举报