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; }