EditDistance(Levenshtein Distance)

Luogu P2758

Problem Statement

设 $A$ 和 $B$ 是两个字符串。我们要用最少的字符操作次数,将字符串 $A$ 转换为字符串 $B$。这里所说的字符操作共有三种:

  1. 删除一个字符;
  2. 插入一个字符;
  3. 将一个字符改为另一个字符。

$A, B$ 均只包含小写字母。

Input

第一行为字符串 $A$;第二行为字符串 $B$;字符串 $A, B$ 的长度均小于 $2000$。

Output

只有一个正整数,为最少字符操作次数。

Sample Input

1
2
sfdqxbw
gfdgw

Sample Output

1
4

Constraints

对于 $100 %$ 的数据,$1 \le |A|, |B| \le 2000$。

Solving

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
const int N = 2005;
const int M = 0; 
int dp[N][N];//表示s1取前i个字符变成s2取前j个字符所需要的最小操作次数
int dp2[N];
string s1,s2;
// a : s1 中插入一个字符的代价
// b : s1 中删除一个字符的代价
// c : s1 中替换一个字符的代价
void solve()
{
    cin >> s1 >> s2;
    int n = s1.size();
    int m = s2.size();
    int a = 1;
    int b = 1;
    int c = 1;
    for(int i=1;i<=n;i++) dp[i][0] = i*b;
    for(int j=1;j<=m;j++) dp[0][j] = j*a;
    //dp[0][0] = 0;
    for(int i=1;i<=n;i++)
    {
        for(int j=1;j<=m;j++)
        {
            if(s1[i-1]==s2[j-1])
            {
                dp[i][j] = dp[i-1][j-1];
            }
            else
            {
                dp[i][j] = min({dp[i-1][j]+b,dp[i][j-1]+a,dp[i-1][j-1]+c});
            }

        }
    }
    cout << dp[n][m];
}
//由状态转移仅依赖上和左上和左:
//一维空间优化后的版本
void solvepromoted()
{
    cin >> s1 >> s2;
    int n = s1.size();
    int m = s2.size();
    int a = 1;
    int b = 1;
    int c = 1;
    int leftup;//记录左上
    int backup;//和leftup形成loop的中间变量
    for(int j=1;j<=m;j++) dp2[j] = j*a;
    //rep(1~n)rep(1~m)的情况下,空间压缩后dp[j-1]为左,更新前的dp[j]为上,leftup为左上;
    for(int i=1;i<=n;i++)
    {       
        //此时leftup代表每一行最开始的值:即dp[i-1][0] == (i-1)*b
        leftup = (i-1)*b;
        dp2[0] = i*b;
        for(int j=1;j<=m;j++)
        {   
            backup = dp2[j];//此时backup记录此时dp2[j]为后续dp2[j+1]作为左上元素
            if(s1[i-1]==s2[j-1])
            {
                dp2[j] = leftup;
            }
            else
            {
                dp2[j] = min({dp2[j]+b,dp2[j-1]+a,leftup+c});
            }
            leftup = backup;
        }
    }
    cout << dp2[m];
}
Licensed under CC BY-NC-SA 4.0
Member of the Qilu University Of Technology ACM-ICPC Association
Built with Hugo
Theme Stack designed by Jimmy