题面
题解
对于两个字符串,我们一般用 f[i][j] 来表示第一个串的前 i 个字母和第二个串的前 j 个字母 ,然后我们划分集合,分三种操作。
删除操作 :f[i][j]我们需要删除a字符串的第i ,那么就需要确保a 的第前 i-1 个字母和b的前 j 个字母相同 ,那么转移方程就是 f[i-1][j]+1(操作步骤)
增加操作:f[i][j]我们需要增加第 i 字母使得 b的 j-1 和 a 原来的 i 匹配 ,那么转移方程就是 f[i][j-1] +1
修改操作 : f[i][j]我们要修改a中的第i个字母为b[j],那么就要使a[i-1]=b[j-1],对于a[i]==b[j],我们就不需要操作次数,对于a[i]!=b[j] ,我们就需要额外一次操作,使得a[i]==a[j]
代码
#include<iostream>
#include<cstdio>
#include<string>
#include<cstring>
#include<algorithm>
using namespace std;
const int N = 1100;
const int INF=0x3f3f3f3f;
int n, m;
char a[N], b[N];
int f[N][N];
int main() {
std::ios::sync_with_stdio(false);
std::cin.tie(nullptr);
cin >> n >> a + 1 >> m >> b + 1;
//让 a[0] 变成 b[0-i] 只能增加操作
for (int i = 0; i <= m; i++) f[0][i] = i;
//让 a[0-i] 变成 b[0] 只能删除操作
for (int i = 0; i <= n; i++) f[i][0] = i;
for (int i = 1; i <= n; i++) {
for (int j = 1; j <= m; j++) {
f[i][j]=INF;
f[i][j] = min(f[i - 1][j], f[i][j - 1]) + 1;
if (a[i] == b[j]) f[i][j] = min(f[i][j], f[i - 1][j - 1]);
else f[i][j] = min(f[i][j], f[i - 1][j - 1] + 1);
}
}
cout << f[n][m] << endl;
return 0;
}