题目链接
题目思路
本来我以为这个题目是和最长子序列有关,用max(da,db)-最长子序列的长度,但是我果然太菜了
随便一组数据就足以证明这个思路是错的
如 rcpw wbl 答案应该是4,而我的答案是3
进入正题
设两个字符串A,B 用一个二维数组f存储状态 一维存A串 一维存B串 一共有如下四种操作:
删:可以看做把A串最后一个字符删去后不再考虑这个字符 所以f(i,j)=min(f(i,j),f(i-1,j)+1);
加:可以看做与B串最后一个字符抵消后不再考虑这个字符 所以f(i,j)=min(f(i,j),f(i,j-1)+1);
改:可以看做删和加的集合 抵消了A、B串最后的两个字符 所以f(i,j)=min(f(i,j),f(i-1,j-1)+1);
当然若A、B串最后一个字符相同就可以不用操作了
此外注意输入时scanf(“%s”,a+1) 那么长度的测量就要strlen(a+1)
最后注意边界的处理
代码
#include<algorithm>
#include<cstring>
#include<cstdio>
#include<map>
using namespace std;
const int maxn=2e3+5;
int da,db,dp[maxn][maxn];
char a[maxn],b[maxn];
int main(){
scanf("%s %s",a+1,b+1);
da=strlen(a+1);
db=strlen(b+1);
for(int i=0;i<=da;i++){//边界处理
dp[i][0]=i;
}
for(int j=0;j<=db;j++){
dp[0][j]=j;
}
for(int i=1;i<=da;i++){
for(int j=1;j<=db;j++){
int k=1;
if(a[i]==b[j]){
k=0;
}
dp[i][j]=min(min(dp[i-1][j]+1,dp[i][j-1]+1),dp[i-1][j-1]+k);
}
}
printf("%d\n",dp[da][db]);
return 0;
}