题目链接:P2758 编辑距离
程序说明:
dp[i][j]表示前a的前 i 个字母和b的前 j 个字母匹配所需要的最少的操作次数,转移方程可以分为三种情况:
删除:a的前 i - 1 个字母和b和前 j 个字母匹配,然后删掉a的第 i 个字母。即dp[i - 1][j] + 1。
增添:a的前 i 个字母和b和前 j - 1 个字母匹配,然后把 b[j] 增添到 a[i] 的后面去。即dp[i][j - 1] + 1。
更改:a的前 i - 1 个字母和b和前 j - 1 个字母匹配,然后把 a[i] 改为 b[j] 。即dp[i - 1][j - 1] + 1。但如果a[i] 和 b[j] 相等,就不需要更改了,即dp[i - 1][j - 1]。
代码如下:
#include <iostream>
#include <cstring>
using namespace std;
const int N = 2010;
char a[N], b[N];
int dp[N][N];
int main() {
cin>>a>>b;
int n = strlen(a), m = strlen(b);
for(int i = n; i >= 1; i--)
a[i] = a[i - 1];
for(int i = m; i >= 1; i--)
b[i] = b[i - 1];
for(int i = 0; i <= m; i++) dp[0][i] = i;
for(int i = 0; i <= n; i++) dp[i][0] = i;
for(int i = 1; i <= n; i++)
for(int j = 1; j <= m; j++) {
dp[i][j] = min(dp[i - 1][j] + 1, dp[i][j - 1] + 1);
if(a[i] == b[j])
dp[i][j] = min(dp[i][j], dp[i - 1][j - 1]);
else
dp[i][j] = min(dp[i][j], dp[i - 1][j - 1] + 1);
}
cout<<dp[n][m]<<endl;
return 0;
}