http://noi.openjudge.cn/ch0206/2988/
折腾了我很久,终于会了。。
设a数组为第一个字符串,b数组为第二个字符串,数组从下标1开始
对于这个问题,我们设f[i][j]为ai到bj的字符串距离(ai为a[1~i], bi为b[1~j])
设a数组的长度为m,b数组的长度为n
初始:
f[i][0] = i; (1<=i<=m)即为a数组有i个元素,b数组有0个元素
当b数组为空时,a数组到b数组的距离绝对是i
例如下面一组数据:
abcde
(空)
那么距离是什么呢?很显然,删除a数组的各个元素即可,因此距离为i
f[0][i] = i; (1<=i<=n)即为a数组有0个元素,b数组有i个元素
当a数组为空时,a数组到b数组的距离也绝对是i
理由同上,只是进行插入操作
那么下面有四种决策方案:
当a[i] = b[j]时
1、f[i][j] = f[i-1][j-1]; 因为不需要进行操作,直接继承前面的即可
例如:
b
deb
当前i=1, j=3, 因为a[i] = b[j]问题可以转化为
(空)
de
即转化为ai-1到bj-1的距离
否则
2、f[i][j] = min(f[i-1][j-1]+1); 把a[i]改为b[i], 使他们相等, 因为改了以后,a[i]=b[j],所以可以转化为上面的方法
例如:
c
deb
当前i=1, j=3, 改a[i]为b[j], 则有
b
deb
就变成上面的那个了,这里不再重复讲。
3、f[i][j] = min(f[i][j-1]+1); 在a[i]后面插入b[j]
例如:
c
deb
当前i=1, j=3, 在a[i]后面插入b[j], 则有
cb
deb
当前a[i+1]=b[j],则有
c
de
所以转化成了
ai到bj-1的距离
c
deb
当前i=1, j=3, 删除a[i], 则有
(空)
deb
即转化为ai-1到bj的距离
最后答案为f[n][m].
#include
#include
#include
#include
#define ms(i,j) memset(i, j, sizeof(i));
using namespace std;
char a[1005], b[1005];
int f[1005][1005];
int main()
{
int t;
scanf("%d\n", &t);
while (t--)
{
scanf("%s%s", a+1,b+1);
int m1 = strlen(a+1), m2 = strlen(b+1);
f[0][0] = 0;
for (int i=1;i<=m1;i++) f[i][0] = i;
for (int i=1;i<=m2;i++) f[0][i] = i;
for (int i=1;i<=m1;i++)
for (int j=1;j<=m2;j++)
{
if (a[i]==b[j])
{
f[i][j] = f[i-1][j-1];
}
else
{
f[i][j] = min(f[i-1][j-1], min(f[i-1][j], f[i][j-1]))+1;
}
}
printf("%d\n", f[m1][m2]);
}
return 0;
}