1276:【例9.20】P2758 编辑距离

题目传送门[(https://www.luogu.com.cn/problem/P2758)]

题目描述

设A和B是两个字符串。我们要用最少的字符操作次数,将字符串A转换为字符串B。这里所说的字符操作共有三种:

1、删除一个字符;

2、插入一个字符;

3、将一个字符改为另一个字符;

!皆为小写字母!

输入格式

第一行为字符串A;第二行为字符串B;字符串A和B的长度均小于2000。

输出格式

只有一个正整数,为最少字符操作次数。

输入输出样例

输入 #1

sfdqxbw
gfdgw

输出 #1

4

注意到删除A[i] 等价于 在B[i]前 插入
 在A[i]前插入与B[i]相同的元素 等价于 删除 B[i]
 修改A[i] 等价于 修改B[i]
为啥?
因为这样的两种操作,都增加了一次操作次数,最终带来了同样的结果
所以,我们只需要对一个串操作,最终的结果没有影响
只对B操作

f[i][j]表示要使A的前i个元素与B的前j个元素相同的最少操作次数

初始化

f[i][0] = i;
f[0][j] = j;

转移

如果A[i]等于B[i],不做修改,f[i][j] = f[i - 1][j - 1]
否则,三种修改方式,在B中加一个,f[i][j] = f[i - 1][j] + 1;
                   在B中删一个,f[i][j] = f[i][j - 1] + 1;
                    在B中改一个,f[i][j] = f[i - 1][j - 1] + 1;
三者取min

代码

#include <cmath>
#include <cstdio>
#include <string>
#include <cstring>
#include <iostream>
#include <algorithm>
#define N 2010
#define INF 1061109000

using namespace std; 

int f[N][N], n1, n2;
string a , b;

int main()
{
	cin >> a >> b;
	for (int i = 0 ; i <= a.size() ; i++)
	{
		for (int j = 0 ; j <= b.size() ; j++)
			f[i][j] = INF;
	}
	f[0][0] = 0;
	f[0][1] = 1;
	f[1][0] = 1;
	for (int i = 0 ; i <= a.size() ; i++)	f[i][0] = i;//重要的初始化 
	for (int j = 0 ; j <= b.size() ; j++)	f[0][j] = j;//重要的初始化 
	//只编辑b[] 
	for (int i = 1 ; i <= a.size() ; i++)
	{
		for (int j = 1 ; j <= b.size() ; j++)
		{
				if(a[i - 1] == b[j - 1])
				{
					f[i][j] = f[i - 1][j - 1];
//					cout << i << " " << j << " " << f[i][j] << endl;				

					continue; 
				}
				f[i][j] = min(f[i][j], f[i - 1][j - 1] +1);
				f[i][j] = min(f[i][j], f[i][j - 1] + 1);
				f[i][j] = min(f[i][j], f[i - 1][j] + 1);
//				cout << i << " " << j << " " << f[i][j] << endl;
		}
	}
/*	for (int j = 1 ; j <= a.size() ; j++)
	{
		for (int i = 1 ; i <= b.size() ; i++)	cout << f[j][i] << " ";
		cout << endl;
	}
*/
	cout << f[a.size()][b.size()] << endl;
	return 0;
}

posted @ 2020-01-21 13:31  _Buffett  阅读(545)  评论(0编辑  收藏  举报