传送门:51nod 1183 编辑距离
在题目中给定了一个定义,编辑距离,想要把a串变为b串对于a中的每个字符可以有三种操作:在a串中增加一个字符,删除一个字符,还有改变一个字符。
这就对应的一个阶段的三种状态
我们来设定阶段dp[i][j]表示a串中的前i个长度和b串中前j个长度中种编辑距离的最小值。
- 当i==0&&j==0的时候,也就是dp[0][0]是0
- 当i==0的时候也就是dp[i][0] =i,这个代表的意思就是b中前j个长度和a串为空的编辑长度为i
- 当j==0的时候,和上面的情况是一样的,dp[0][j] = j
- 当a[i] == b[j]的时候,也就是代表着一位不是编辑距离,这个时候dp[i][j] = min(dp[i-1][j],dp[i][j-1],dp[i-1][j-1]);dp[i-1][j]表示删除操作,dp[i][j-1]表示的增加操作,dp[i-1][j-1]表示修改操作
所以我们就不难写出状态方程:当a[i] == b[j]的时候dp[i][j] = min(min(dp[i-1][j]+1,dp[i][j-1]+1),dp[i-1][j-1]);
当a[i]!=b[j]的时候dp[i][j] = min(min(dp[i-1][j]+1,dp[i][j-1]+1),dp[i-1][j-1]+1);
AC代码
#include<stdio.h>
#include<string.h>
#include<algorithm>
using namespace std;
const int MAXN = 1005;
int dp[MAXN][MAXN];
int main()
{
char a[MAXN];
char b[MAXN];
while(scanf("%s%s",a,b)!=EOF)
{
int lenA = strlen(a);
int lenB = strlen(b);
memset(dp,0,sizeof dp);
for(int i=1;i<=lenA;i++)
{
dp[i][0] = i;
for(int j=1;j<=lenB;j++)
{
dp[0][j] = j;
if(a[i-1] == b[j-1])
dp[i][j] = min(min(dp[i-1][j]+1,dp[i][j-1]+1),dp[i-1][j-1]);
else
dp[i][j] = min(min(dp[i-1][j]+1,dp[i][j-1]+1),dp[i-1][j-1]+1);
//printf("[%d]",dp[i][j]);
}
// printf("\n");
}
printf("%d\n",dp[lenA][lenB]);
}
return 0;
}