1. 程式人生 > >算法56-----最小編輯代價【動態規劃】

算法56-----最小編輯代價【動態規劃】

狀態 tro 如果 for 字符串 技術 gin 給定 clas

一、題目:最小編輯代價

給定兩個字符串str1和str2,再給定三個整數ic,dc,rc,分別代表插入、刪除、替換一個字符的代價,返回將str1編輯成str2的最小代價。
舉例:
str1="abc" str2="adc" ic=5 dc=3 rc=2,從"abc"編輯到"adc"把b替換成d代價最小,為2;
str1="abc" str2="adc" ic=5 dc=3 rc=10,從"abc"編輯到"adc",先刪除b再插入d代價最小,為8;

思路:動態規劃:時間O(M*N),空間O(M*N)

動態規劃表:dp[i][j]表示str1[0......i-1]編輯成str2[0......j-1]的最小編輯代價,dp大小為(M+1)*(N+1)是為了從空串開始計算,即dp[0][0]表示空串編輯到空串的最小編輯代價。

技術分享圖片

技術分享圖片

狀態方程:
  • 初始化:

dp[0][0] = 0

dp[0][j] = j * len(s2)

dp[i][0] = i * len(s1)

  • dp[i][j] = min( dp[i][j-1]+ic , dc+dp[i-1][j] , dp[i-1][j-1] + rc 【如果str1[i-1]==str2[j-1],rc = rc,否則,rc = 0】)
1.dp[0][0]表示空串編輯成空串,故dp[0][0]=0;
2.求第一行dp[0][j],空串編輯成str2[0....j-1],則dp[0][j]=ic*j;
3.求第一列dp[i][0],str1[0......i-1]編輯成空串,則dp[i][0]=dc*i
;
4.求dp[i][j],即str1[0....i-1]編輯成str2[0.....j-1],三種可能的途徑:
<1>str1[0....i-1]先編輯成str2[0.....j-2],再由str2[0.....j-2]插入到str2[0.....j-1],即 dp[i][j-1] + ic;
<2>str1[0....i-1]先編輯成str1[0.....i-2],再由str1[0.....i-2]刪除到str2[0.....j-1],即 dp[i-1][j] + dc;
<3>如果str1[i-1]==str2[j-1],則 dp[i][j] = dp[i-1][j-1];
如果str1[i-1]!=str2[j-1],則 dp[i][j] = dp[i-1][j-1] + rc
; 最後比較三種途徑的最小值,即dp[i][j]的值。 技術分享圖片

代碼:

def mincost(s1,s2,ic,dc,rc):
    m , n = len(s1) , len(s2)
    if not s1:
        return n*ic
    if not s2:
        return m*dc
    dp = [[0] * (n+1) for i in range(m+1)]
    for i in range(1,n + 1):
        dp[0][i] = ic * i
    for j in range(1,m + 1):
        dp[j][0] = dc * j
    for i in range(1,m+1):
        for j in range(1,n+1):
            if s1[i-1] == s2[j-1]:
                dp[i][j] = dp[i-1][j-1]
            else:
                dp[i][j] = dp[i-1][j-1] + rc
            dp[i][j] = min( dp[i][j] , dp[i-1][j] + dc , dp[i][j-1] + ic)
    return dp[-1][-1]
s1 = ab12cd3
s2 = abcdf
ic , dc , rc = 5,3,2
mincost(s1,s2,ic,dc,rc)

算法56-----最小編輯代價【動態規劃】