本题链接(单击这里)
题意:
这题是一个编辑距离题,编辑距离是指两个字串之间,由一个转成另一个所需的最少编辑操作次数(可以替换、插入、删除)。
思路:
用表格来记录状态的变化。
第一个表格是dp初始化后的状态。
dp[i][0]=dp[0][i]=i;
为什么这样初始化:假如有一个字符串什么都没有,而另一个有5个字符是不是要操作5次,11个是不是要操作11次;
也可以这样想,想要5个字符变为没有字符是不是要删除5次。
A | G | T | A | A | G | T | A | G | G | C | |||
0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | ||
A | 1 | ||||||||||||
G | 2 | ||||||||||||
T | 3 | ||||||||||||
C | 4 | ||||||||||||
T | 5 | ||||||||||||
G | 6 | ||||||||||||
A | 7 | ||||||||||||
C | 8 | ||||||||||||
G | 9 | ||||||||||||
C | 10 | ||||||||||||
拆分一下,先假如只有一个字母的串变成11个字母的串。
再拆一下,行两个字母,列一个字母。
A | G | ||
0 | 1 | 2 | |
A | 1 | 0 | 1 |
A | G | T | A | A | G | T | A | G | G | C | |||
0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | ||
A | 1 | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 |
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);
A | G | T | A | A | G | T | A | G | G | C | |||
0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | ||
A | 1 | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | |
G | 2 | 1 | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | |
T | 3 | 2 | 1 | 1 | 2 | 3 | 4 | 5 | 6 | 6 | 7 | 8 | |
C | 4 | 3 | 2 | 1 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 7 | |
T | 5 | 4 | 3 | 2 | 2 | 2 | 3 | 3 | 4 | 5 | 6 | 7 | |
G | 6 | 5 | 4 | 3 | 3 | 3 | 2 | 3 | 4 | 4 | 5 | 6 | |
A | 7 | 6 | 5 | 4 | 3 | 3 | 3 | 3 | 3 | 4 | 5 | 6 | |
C | 8 | 7 | 6 | 5 | 4 | 4 | 4 | 4 | 4 | 4 | 5 | 5 | |
G | 9 | 8 | 7 | 6 | 5 | 5 | 4 | 5 | 5 | 4 | 4 | 5 | |
C | 10 | 9 | 8 | 7 | 6 | 6 | 5 | 5 | 6 | 5 | 5 | 4 | |
#include <iostream>
#include <cstdio>
#include <algorithm>
using namespace std;
char a[1010];
char b[1010];
int dp[1010][1010];
int main()
{
int ai,bi;
while(~scanf("%d%s",&ai,a+1))
{
scanf("%d%s",&bi,b+1);
int Max=max(ai,bi);
for(int i=0;i<=Max;i++)
dp[i][0]=dp[0][i]=i;
for(int i=1;i<=ai;i++)
for(int j=1;j<=bi;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);
}
printf("%d\n",dp[ai][bi]);
}
return 0;
}