Acw902.最短编辑距离

902.最短编辑距离

题目描述

给定两个字符串 \(A\)\(B\),现在要将 \(A\) 经过若干操作变为 \(B\),可进行的操作有:

  1. 删除–将字符串 \(A\) 中的某个字符删除。
  2. 插入–在字符串 \(A\) 的某个位置插入某个字符。
  3. 替换–将字符串 \(A\) 中的某个字符替换为另一个字符。

现在请你求出,将 \(A\) 变为 \(B\) 至少需要进行多少次操作。

输入描述

第一行包含整数 \(1\leq n \leq 1000\) ,表示字符串 \(A\) 的长度。
第二行包含一个长度为 \(n\) 的字符串 \(A\)
第三行包含整数 \(1\leq m \leq 1000\) ,表示字符串 \(B\) 的长度。
第四行包含一个长度为 \(m\) 的字符串 \(B\)
字符串中均只包含大小写字母。

输出描述

输出一个整数,表示最少操作次数。

解题思路

根据题目很容易想到暴力求解,但是复杂度显然不允许,可以发现长字符串的变化可以由短字符串得到,因此考虑使用动态规划来解决这个问题。
首先创建一个二维的dp数组,一维删除,一维插入。 \(dp[i][0]\) 表示将前 \(i\) 个字符的字符串变为空字符串所需的操作数,即删除操作的次数; \(dp[0][i]\) 表示将空字符串变为前 \(i\) 个字符的字符串所需的操作数,即插入操作的次数。总的来说, \(dp[i][j]\) 表示把 \(s1[1]\) - \(s1[i]\) 变成 \(s2[1]\) - \(s2[j]\) 需要操作的最少操作次数。
初始化 \(dp[0][0]\)\(0\) ,表示从空字符串到空字符串需要操作的次数是 \(0\)
对于每个字符 \(s1[i]\)\(s2[j]\) ,如果它们不同,则可以有三种操作:

  1. 删除 \(s1[i]\) ,即 \(dp[i-1][j]+1\)
  2. 插入 \(s2[j]\) ,即 \(dp[i][j-1]+1\)
  3. 替换 \(s1[i]\)\(s2[j]\) :即 \(dp[i-1][j-1]+1\)

如果它们相同,则不需要进行操作,操作数为 \(dp[i-1][j-1]\)
因此我们可以得到以下状态转移方程:

\[dp[i][j]=min \begin{cases} dp[i−1][j]+1 , (删除操作) \\ dp[i][j−1]+1 , (插入操作) \\ dp[i−1][j−1]+cost , (替换操作,如果s1[i-1]==s2[j-1],cost=0,否则cost=1) \end{cases} \]

结合上述步骤即可得到最终答案。

代码实现

#include <bits/stdc++.h>

using i64 = long long;
const int inf = 2e9;

int main() {
    std::ios::sync_with_stdio(false);
    std::cin.tie(0);
    std::cout.tie(0);
    int n, m;
    std::string s1, s2;
    std::cin >> n >> s1 >> m >> s2;
    s1 = " " + s1;
    s2 = " " + s2;
    std::vector<std::vector<int>> dp(n + 1, std::vector<int>(m + 1, inf));
    for (int i = 1; i <= n; i++) {
        dp[i][0] = i;
    }
    for (int i = 1; i <= m; i++) {
        dp[0][i] = i;
    }
    dp[0][0] = 0;
    for (int i = 1; i <= n; i++) {
        for (int j = 1; j <= m; j++) {
            dp[i][j] = std::min(dp[i - 1][j], dp[i][j - 1]) + 1;
            if (s1[i] == s2[j]) {
                dp[i][j] = std::min(dp[i][j], dp[i - 1][j - 1]);
            } else {
                dp[i][j] = std::min(dp[i][j], dp[i - 1][j - 1] + 1);
            }
        }
    }
    std::cout << dp[n][m];
}
posted @ 2024-08-03 02:37  udiandianis  阅读(42)  评论(0)    收藏  举报