1276:【例9.20】编辑距离
时间限制: 1000 ms 内存限制: 65536 KB
提交数: 3678 通过数: 1452
【题目描述】
设A和B是两个字符串。我们要用最少的字符操作次数,将字符串A转换为字符串B。这里所说的字符操作共有三种:
1、删除一个字符;
2、插入一个字符;
3、将一个字符改为另一个字符。
对任意的两个字符串A和B,计算出将字符串A变换为字符串B所用的最少字符操作次数。
【输入】
第一行为字符串A;第二行为字符串B;字符串A和B的长度均小于2000。
【输出】
只有一个正整数,为最少字符操作次数。
【输入样例】
sfdqxbw
gfdgw
【输出样例】
4
思路:
这是一道动态规划的题目,思路有点像最长公共子序列,但是不问完全一样。这道题中求公共子序列没有啥意义,因为有些字母是要删除的,有些字母是要变换的,呃,就是跟公共子序列么有关系,我一开始想错了。但是最长公共子序列的思想是可以借鉴的。
这种题型:利用动态规划的基本思想,很多题目都是从后向前考虑。假设前一步的结果已经知道了,分析在前面结果已经知道的基础上,得出最后一步结果需要决策的方案。在多种选择方案中给出结果(最优或者求和等)
设L[x][y] 表示的是两个字符串从开始分别到x和y长度所求的结果(最少编辑数)。也是从后向前考虑,如果两个字符串现在考虑的最后一个字母a[x]=b[y]的话,就不用进行编辑。如果两个字符串的a[x]!=b[y]的话,就可以考虑编辑一下了,题目中给出了三种编辑方式(一般给出三种办法,就是在三种策略中选取最优值),那么就借助前一步(假设已经知道了)的结果选取最优结果,即 min(L[x][y-1]+1, L[x-1][y]+1, L[x-1][y-1]+1)。分别表示三种方案,即在字符串a的x位后面插入b[y];删除a[x];将a[x]变成b[y]。(进行修改了次数就要加1)
状态转移方程:
L[x][y] = L[x-1][y-1] 如果a[x]=b[y]
L[x][y] = min(L[x][y-1]+1, L[x-1][y]+1, L[x-1][y-1]+1) 如果a[x]!=b[y]
初始化:
其中有一个的位置为0(x=0 或 y=0)那另一个要编辑的次数就是它本身的长度。
本题代码:
#include<iostream>
#include<string.h>
#include<stdio.h>
#include<math.h>
using namespace std;
//不能直接最长公共子序列 但是思路有点相似
//给了三种方案 那就在每次做小的决策的时候从中选出一种最优的
int l[2001<