题解【AcWing902】最短编辑距离

题面

经典的最长公共子序列模型。

我们设 (dp_{i,j}) 表示 (a_{1...i})(b_{1...j}) 匹配上所需的最少操作数。

考虑删除操作,我们将 (a_i) 删除后 (a_{1...i}) 就与 (b_{1...j}) 匹配上了,说明原来 (a_{1...i-1})(b_{1...j}) 就是匹配上的,转移方程就是 (dp_{i,j}=dp_{i-1,j}+1)

插入操作与删除操作同理,转移方程是 (dp_{i,j}=dp_{i,j-1}+1)

考虑替换操作,

  • 如果 (a_i=b_j),则 (dp_{i,j}=dp_{i-1,j-1})
  • 如果 (a_i e b_j),则 (dp_{i,j}=dp_{i-1,j-1}+1)

转移时这 (3) 种情况取 (min) 即可。

边界条件: (dp_{i,0}=i)(dp_{0,i}=i)

#include <bits/stdc++.h>

using namespace std;

int n, m, ans, dp[1003][1003];
char a[1003], b[1003];

int main()
{
    scanf("%d%s", &n, a + 1);
    scanf("%d%s", &m, b + 1);
    for (int i = 1; i <= n; i+=1) dp[i][0] = i;
    for (int i = 1; i <= m; i+=1) dp[0][i] = i;
    for (int i = 1; i <= n; i+=1)
        for (int j = 1; j <= m; j+=1)
        {
            dp[i][j] = min(dp[i][j - 1] + 1, dp[i - 1][j] + 1);
            if (a[i] == b[j]) dp[i][j] = min(dp[i][j], dp[i - 1][j - 1]);
            else dp[i][j] = min(dp[i][j], dp[i - 1][j - 1] + 1);
        }
    cout << dp[n][m] << endl;
    return 0;
}
原文地址:https://www.cnblogs.com/xsl19/p/12324020.html