题目描述
【题目描述】
设A和B是两个字符串。我们要用最少的字符操作次数,将字符串A转换为字符串B。这里所说的字符操作共有三种:
1、删除一个字符;
2、插入一个字符;
3、将一个字符改为另一个字符。
对任意的两个字符串A和B,计算出将字符串A变换为字符串B所用的最少字符操作次数。
【输入】
第一行为字符串A;第二行为字符串B;字符串A和B的长度均小于2000。
【输出】
只有一个正整数,为最少字符操作次数。
【输入样例】
sfdqxbw
gfdgw
【输出样例】
4
题目分析
本题目与最长公共子序列的思路有点类似包括状态的表示和划分,具体可参考最长公共子序列。
本题目中的状态表示的为前i个字符变为前j个字符的最少操作数
状态划分为第i个字符有3种操作情况,增加,删除,修改.其中如果第i个字符与第j个相同则不用操作即为dp[i][j]=dp[i-1][j-1]。
1.增加相当于前i个字符已经与j-1相同,我们再加上一个字符就行所以dp[i][j]=dp[i][j-1]+1
2.删除相当于前i-1个字符已经与前j个字符相同所以删除最后一个就好dp[i][j]=dp[i-1][j]+1
3.修改相当于前i-1与前j-1个字符相同,只有最后一个不同所以dp[i][j]=dp[i-1][j-1]+1
最后我们取三种情况的最大值即可。
代码
#include<bits/stdc++.h>
using namespace std;
const int N=2010;
string a,b;
int f[N][N];
int main(){
cin>>a>>b;
a=" "+a;
b=" "+b;
for(int i=1;i<=a.size();i++){
f[i][0]=i;
}
for(int j=1;j<=b.size();j++){
f[0][j]=j;
}
for(int i=1;i<=a.size();i++){
for(int j=1;j<=b.size();j++){
if(a[i]==b[j]) f[i][j]=f[i-1][j-1];
else f[i][j]=min(f[i][j-1]+1,min(f[i-1][j]+1,f[i-1][j-1]+1));
}
}
cout<<f[a.size()][b.size()]<<endl;
return 0;
}