传送门
http://codevs.cn/problem/2598/
题目大意
将一个字符串通过删除一个字符,添加一个字符,将一个字符换为其他字符三种操作,使两个字符串相同的最小操作数
题解
- 我们考虑转移情况,3种操作,3种转移,我们假设dp[i,j]为a的前i位和b的前j位的最小操作值,我们对于将一个字符换为其他字符的操作,如果a[I]=b[J]那么dp[i,j]=dp[i-1,j-1]否则dp[i,j]=dp[i-1,j-1]+1,删除操作和添加操作其实是相同的,也就是a子串后加一个字符也就是删除b子串最后的失配字符,所以dp[i,j]可以说dp[i,j-1] (a的i位与j-1位匹配成功)在a的i后面加上b[j],即dp[i,j]=dp[i,j-1]+1,也可以是dp[i-1,j] (a的i-1位与j位匹配成功)在b的j位后加上a[i],即dp[i,j]=dp[i-1,j]+1
综上所述
dp[i,j]=min⎧⎩⎨⎪⎪⎪⎪⎪⎪dp[i−1,j]+1dp[i,j−1]+1dp[i,j] (a[i]=b[j])dp[i,j]+1 (a[i]<>b[j]) - 然后我们考虑边界,显然dp[0,0]=0,dp[0,j]=0,dp[i,0]=0
var
dp:array[0..2005,0..2005]of longint;
i,j,k:longint;
a,b:ansistring;
n,m:longint;
function min(a,b:longint):longint;
begin
if a<b
then exit(a)
else exit(b);
end;
begin
readln(a); readln(b);
n:=length(a); m:=length(b);
for i:=1 to n do
dp[i,0]:=i;
for j:=1 to m do
dp[0,j]:=j;
for i:=1 to n do
for j:=1 to m do
begin
dp[i,j]:=min(dp[i,j-1],dp[i-1,j])+1;
if a[i]=b[j]
then 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);
end;
writeln(dp[n,m]);
end.