题目描述
设 A 和 B 是两个字符串。我们要用最少的字符操作次数,将字符串 A 转换为字符串 B。这里所说的字符操作共有三种:
- 删除一个字符;
- 插入一个字符;
- 将一个字符改为另一个字符。
A,B 均只包含小写字母。
输入格式
第一行为字符串 A;第二行为字符串 B;字符串 ,A,B 的长度均小于 20002000。
输出格式
只有一个正整数,为最少字符操作次数。
输入输出样例
输入 #1复制
sfdqxbw gfdgw
输出 #1复制
4
说明/提示
对于 100%100% 的数据1≤∣A∣,∣B∣≤2000。
本题我们先看一幅图。
我们根据这幅图去构思一个转移方程。dp(i,j)表示将A串1~i个字符通过提示三种操作转换为B串1~j个字符的最少操作次数。
通过观察上图我们可以发现在i=3,b=3时a[i]=b[i]。dp(i,j)=dp(i-1,j-1),因为a[3]=b[3],此时对于a[3]、b[3],我们不需要进行操作所以dp(3,3)=dp(2,2)。
而在i=4,j=3时a[i]!=a[b],此时我们就需要对a[4]进行处理。如果我们删除a[4]则dp(4,3)=dp(3,3)+1;如果我们在a[4]后增加一个字符b[3]则dp(4,3)=dp(4,2)+1;如果我们将a[4]换成b[3]则dp(4,3)=dp(3,2).所以a[i]!=b[j]时dp(i,j)=min(dp(i-1,j),dp(i,j-1),dp(i-1,j-1))+1;
总结
1.a[i]=b[j],
dp(i,j)=dp(i-1,j-1);
2.a[i]!=b[j];
dp(i,j)=min(dp(i-1,j),dp(i,j-1),dp(i-1,j-1))+1;
#include<stdio.h>
#include<string.h>
int dp[2005][2005];
char a[2005],b[2005];
int min(int x,int y)
{
if(x<y)
return x;
return y;
}
int main()
{
int n,m,t;
scanf("%s\n%s",a,b);
n=strlen(a);
m=strlen(b);
for(int i=1;i<=n;i++)
dp[i][0]=i;
for(int i=1;i<=m;i++)
dp[0][i]=i;
for(int i=1;i<=n;i++)
{
for(int j=1;j<=m;j++)
{
if(a[i-1]==b[j-1])
dp[i][j]=dp[i-1][j-1];
else
dp[i][j]=min(min(dp[i-1][j],dp[i][j-1]),dp[i-1][j-1])+1;
}
}
printf("%d",dp[n][m]);
return 0;
}