acwing 902 最短编辑距离 (线性DP)

题面

在这里插入图片描述

题解在这里插入图片描述

对于两个字符串,我们一般用 f[i][j] 来表示第一个串的前 i 个字母和第二个串的前 j 个字母 ,然后我们划分集合,分三种操作。

删除操作 :f[i][j]我们需要删除a字符串的第i ,那么就需要确保a 的第前 i-1 个字母和b的前 j 个字母相同 ,那么转移方程就是 f[i-1][j]+1(操作步骤)

增加操作:f[i][j]我们需要增加第 i 字母使得 b的 j-1 和 a 原来的 i 匹配 ,那么转移方程就是 f[i][j-1] +1

修改操作 : f[i][j]我们要修改a中的第i个字母为b[j],那么就要使a[i-1]=b[j-1],对于a[i]==b[j],我们就不需要操作次数,对于a[i]!=b[j] ,我们就需要额外一次操作,使得a[i]==a[j]

代码

#include<iostream>
#include<cstdio>
#include<string>
#include<cstring>
#include<algorithm>

using namespace std;
const int N = 1100;
const int INF=0x3f3f3f3f;

int n, m;
char a[N], b[N];
int f[N][N];

int main() {
    
    

    std::ios::sync_with_stdio(false);
    std::cin.tie(nullptr);

    cin >> n >> a + 1 >> m >> b + 1;

    //让 a[0] 变成 b[0-i] 只能增加操作
    for (int i = 0; i <= m; i++) f[0][i] = i;
    //让 a[0-i] 变成 b[0] 只能删除操作
    for (int i = 0; i <= n; i++) f[i][0] = i;

    for (int i = 1; i <= n; i++) {
    
    
        for (int j = 1; j <= m; j++) {
    
    
            f[i][j]=INF;
            f[i][j] = min(f[i - 1][j], f[i][j - 1]) + 1;
            if (a[i] == b[j]) f[i][j] = min(f[i][j], f[i - 1][j - 1]);
            else f[i][j] = min(f[i][j], f[i - 1][j - 1] + 1);
        }
    }

    cout << f[n][m] << endl;

    return 0;
}

猜你喜欢

转载自blog.csdn.net/qq_44791484/article/details/114842516