[CodeVS 2598] 编辑距离问题

传送门

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]=mindp[i1,j]+1dp[i,j1]+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.

你可能感兴趣的:([CodeVS 2598] 编辑距离问题)