1. 題目
題目鏈接:P2758「編輯距離」 。
題目描述
設A和B是兩個字符串。我們要用最少的字符操作次數,將字符串A轉換爲字符串B。這裏所說的字符操作共有三種:
1、刪除一個字符;
2、插入一個字符;
3、將一個字符改爲另一個字符;
!皆爲小寫字母!
輸入格式
第一行爲字符串A;第二行爲字符串B;字符串A和B的長度均小於2000。
輸出格式
只有一個正整數,爲最少字符操作次數。
輸入輸出樣例
輸入 #1
sfdqxbw
gfdgw
輸出 #1
4
2. 題解
分析
易知編輯距離是對稱的,即將字符串 A 變成字符串 B 和將字符串 B 變成字符串 A 所需的最小操作數是一樣的,也就是字符串 A、B 之間的編輯距離。然後直覺感覺就是一道簡單的 dp 題:
- 假設 f[i][j] 表示字符串 A[0..i-1] 和 B[0..j-1] 之間的編輯距離,則有如下轉移方程:
- 如果 A[i] == B[j],則 f[i][j] = f[i-1][j-1]。
- 如果 A[i] != B[j],則 f[i][j] = min(f[i-1][j-1], f[i-1][j], f[i][j-1]) + 1。
- 邊界條件爲:f[0][0] = 0, f[i][0] = i, f[0][j] = j。
代碼
# include <bits/stdc++.h>
# define MAXLEN 2005
using namespace std;
char a[MAXLEN], b[MAXLEN];
int f[MAXLEN][MAXLEN];
int main()
{
scanf("%s%s", a, b);
int alen = strlen(a);
int blen = strlen(b);
f[0][0] = 0;
for(int i = 1; i <= alen; ++i) {
f[i][0] = i;
}
for(int j = 1; j <= blen; ++j) {
f[0][j] = j;
}
for(int i = 1; i <= alen; ++i) {
for(int j = 1; j <= blen; ++j) {
if(a[i-1] == b[j-1]) {
f[i][j] = f[i-1][j-1];
} else {
f[i][j] = min(f[i-1][j], min(f[i][j-1], f[i-1][j-1])) + 1;
}
}
}
int ans = f[alen][blen];
printf("%d\n", ans);
return 0;
}