题目:
给定两个字符串 AA 和 BB,现在要将 AA 经过若干操作变为 BB,可进行的操作有:
- 删除–将字符串 AA 中的某个字符删除。
- 插入–在字符串 AA 的某个位置插入某个字符。
- 替换–将字符串 AA 中的某个字符替换为另一个字符。
现在请你求出,将 AA 变为 BB 至少需要进行多少次操作。
输入格式
第一行包含整数 nn,表示字符串 AA 的长度。
第二行包含一个长度为 nn 的字符串 AA。
第三行包含整数 mm,表示字符串 BB 的长度。
第四行包含一个长度为 mm 的字符串 BB。
字符串中均只包含大写字母。
解析:
本题的dp需要分析三种状态:
1,a[i]通过删除最后一个字符变成b[j];
2,a[i]通过在最后加上一个字符变成b[j];
3,a[i]通过把最后一个字符替换变成b[j];
第一种情况对应的方程:dp[i-1][j]+1(此时前a的i-1项和b的前j项已经相同);
第二种情况对应的方程:dp[i][j-1]+1(此时前a的i项和b的前j-1项已经相同);
第三种情况对应的方程:dp[i-1][j-1]+1或dp[i-1][j-1](此时前a的i-1项和b的前j-1项已经相同);
第一二种情况的状态转移方程dp[i][j]=min(dp[i-1][j]+1,dp[i][j-1]+1);
第三种状态转移方程分两类a[i]与b[j]相同或不同
if(a[i]==b[j]){
dp[i][j]=min(dp[i][j],dp[i-1][j-1]);
}
else {
dp[i][j]=min(dp[i][j],dp[i-1][j-1]+1);
}
代码实现:
#include <iostream>
#include <algorithm>
using namespace std;
const int N=1005;
int n,m;
char a[N],b[N];
int dp[N][N];
int main(){
cin>>n>>a+1>>m>>b+1;
for(int i=0;i<=n;i++) dp[i][0]=i;//初始化(即把a从1到i变成b[0]需要i步,删除a1
到i)
for(int i=0;i<=m;i++) dp[0][i]=i;//初始化(即把a从1到i增加i个字符)
for(int i=1;i<=n;i++){
for(int j=1;j<=m;j++){
dp[i][j]=min(dp[i-1][j]+1,dp[i][j-1]+1);
if(a[i]==b[j]){
dp[i][j]=min(dp[i][j],dp[i-1][j-1]);
}
else {
dp[i][j]=min(dp[i][j],dp[i-1][j-1]+1);
}
}
}
cout<<dp[n][m];
return 0;
}
样例数据: