P2758 编辑距离

题目描述

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

1、删除一个字符;

2、插入一个字符;

3、将一个字符改为另一个字符;

!皆为小写字母!

输入格式

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

输出格式

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

样例数据

输入

sfdqxbw
gfdgw

输出

4

分析

字符串从$0$开始,所以处理时要判断是否符合$a_{i-1}=b_{j-1}$。本题对字符串的操作有四种$$\text{删除}\ Dp_{i-1,j}+1\\\text{添加}\ Dp_{i,j-1}+1\\\text{替换}\ Dp_{i-1,j-1}+1\\\text{不变}\ Dp_{i-1,j-1}$$所以不难得到状态转移方程为$$Temp=min\left \{Dp_{i-1,j},Dp_{i,j-1}\right \}\\Dp_{i,j}=min\left \{Temp,Dp_{i-1,j-1}\right \}+1$$

代码

#include <bits/stdc++.h>

#define Space putchar(' ')
#define Enter puts("")
#define MAXN 100010
#define int long long

using namespace std;

typedef long long ll;
typedef double Db;

inline ll Read() {
    ll Ans = 0;
    char Ch = getchar() , Las = ' ';
    while(!isdigit(Ch)) {
        Las = Ch;
        Ch = getchar();
    }
    while(isdigit(Ch)) {
        Ans = (Ans << 3) + (Ans << 1) + Ch - '0';
        Ch = getchar();
    }
    if(Las == '-')
        Ans = -Ans;
    return Ans;
}

inline void Write(ll x) {
    if(x < 0) {
        x = -x;
        putchar('-');
    }
    if(x >= 10)
        Write(x / 10);
    putchar(x % 10 + '0');
}

char a[MAXN] , b[MAXN];
int Dp[5000][5000];
int Length_A , Length_B;

signed main()
{
    scanf("%s %s" , a , b);
    Length_A = strlen(a);
    Length_B = strlen(b);
    for(int i = 1; i <= Length_A; i++)
        Dp[i][0] = i;
    for(int i = 1; i <= Length_B; i++)
        Dp[0][i] = i;
    for(int i = 1; i <= Length_A; i++)
        for(int j = 1; j <= Length_B; j++)
        {
            if(a[i - 1] == b[j - 1])
            {
                Dp[i][j] = Dp[i - 1][j - 1];
                continue;    
            }
            int Temp = min(Dp[i - 1][j] , Dp[i][j - 1]);
            Dp[i][j] = min(Temp , Dp[i - 1][j - 1]) + 1;
        }
    Write(Dp[Length_A][Length_B]);
    return 0;
}

 

posted @ 2021-06-15 20:01  Tenderfoot  阅读(64)  评论(0编辑  收藏  举报