AtCoder Beginner Contest 185E Sequence Matching | String dp

Title link: https://atcoder.jp/contests/abc185/tasks/abc185_e

Main idea:

Given two strings, you can delete any letter in the two strings

The ultimate goal is to make the two strings the same length

Define the weight x = the total number of deleted characters, y = the total number of positions A[i] != B[i] under the final string

Ask the minimum value of x+y

Question idea:

Classic string dp

Considering that dp[i][k] represents the first i of the string A and the first B of the string, forming a string of the same length, the minimum value of x+y

Then for any position (i,k)

That is:

1. Delete i and keep k

2. Delete k and keep i

3. Delete i and delete k

4. Keep i and keep k

Just enumerate the four cases and transfer it, and for the third case, there is no need to enumerate because it is meaningless

So just consider the boundary conditions

This is ABCak

Code:

/*** keep hungry and calm CoolGuang!  ***/
#pragma GCC optimize("Ofast","unroll-loops","omit-frame-pointer","inline")
#pragma GCC optimize(3)
#include <bits/stdc++.h>
#include<stdio.h>
#include<queue>
#include<algorithm>
#include<string.h>
#include<iostream>
#define debug(x) cout<<#x<<":"<<x<<endl;
#define d(x) printf("%lld\n",x);
typedef long long ll;
typedef unsigned long long ull;
using namespace std;
const ll INF= 1e18;
const ll maxn = 4e5+700;
const int mod= 1e9+7;
const int up = 1e9;
template<typename T>inline void read(T &a){char c=getchar();T x=0,f=1;while(!isdigit(c)){if(c=='-')f=-1;c=getchar();}
while(isdigit(c)){x=(x<<1)+(x<<3)+c-'0';c=getchar();}a=f*x;}
ll n,m,p;
ll dp[1005][1005];
ll a[maxn],b[maxn];
int main(){
    read(n);read(m);
    for(int i=1;i<=n;i++) read(a[i]);
    for(int i=1;i<=m;i++) read(b[i]);
    for(int i=1;i<=n;i++)
        for(int k=1;k<=m;k++)
            dp[i][k] = INF;
    dp[0][0] = 0;
    for(int i=1;i<=n;i++) dp[i][0] = i;
    for(int k=1;k<=m;k++) dp[0][k] = k;
    for(int i=1;i<=n;i++){
        for(int k=1;k<=m;k++){
            dp[i][k] = min(dp[i-1][k]+1,dp[i][k-1]+1);
            dp[i][k] = min(dp[i][k],dp[i-1][k-1]+(a[i]!=b[k]));
        }
    }
    ll ans = INF;
    printf("%lld\n",dp[n][m]);
    return 0;
}
/***
2 4
2 3
1 1 2 3
***/

 

Guess you like

Origin blog.csdn.net/qq_43857314/article/details/111146562