题目链接:

https://www.acwing.com/problem/content/904/

题目大意:

给定两个字符串,\(a\)\(b\),现要将 \(a\) 变成 \(b\)
可以进行的操作有:
1.将 \(a\) 中某个字符删除
2.在 \(a\) 的某个位置插入某个字符
3.将 \(a\) 中的某个字符替换成另一个字符
问,最少几次操作可以实现 \(a\) 变成 \(b\)

思路:

定义 \(f[i][j] 为将 a 的前 i 个字符变成 b 的前 j\) 个字符的最少操作次数。接下来考虑转移,\(f[i][j]\) 可以从哪些情况下转移过来?
\(1.f[i][j - 1],实现了 a 的前 i 个变成 b 的前 j - 1 个字符,但是我们在 b 中加入了第 j 个字符,所以 a 也要再加入一个字符,操作次数 + 1。\)
\(2.f[i - 1][j],实现了 a 的前 i - 1 个变成了 b 的前 j 个,说明我们加入的第 i 个字符多余了,删掉,次数 + 1。\)
\(3.f[i - 1][j],这种情况下,我们加入了 a 的第 i 个,b 的第 j 个,如果两个相同,那么不用再操作,如果不同,那需要进行一次替换操作。\)

代码:

#include <bits/stdc++.h>
using namespace std;
const int N = 1e3 + 10;
int n, m, f[N][N];
char a[N], b[N];
int main(){
	cin >> n >> a + 1 >> m >> b + 1;
	for (int i = 0; i <= m; i++) f[0][i] = i;
	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] = min(min(f[i - 1][j], f[i][j - 1]) + 1, f[i - 1][j - 1] + (a[i] != b[j]));
	cout << f[n][m] << "\n";
	return 0;
}
posted on 2022-02-11 21:25  Hamine  阅读(58)  评论(0编辑  收藏  举报