演算法學習——動態規劃 例題:兩字串轉換權最小問題(java)
阿新 • • 發佈:2019-01-12
題目 :
給定兩個字串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=100.從abc編輯成adc,先刪除d,然後插入d是代價最小的, 所以返回8.
動態規劃:
假設str1的長度為m,str2的長度為N,首先生成大小為(M+1)*(n+1)的矩陣dp,dp[i][j]的值代表str1[0...i-1]編輯成str2[0....j-1] 的最小代價,
思想理解(本人的通俗理解):
動態規劃無非就是動態的決定下一步的走向,不斷規劃下面的方向然後得到所想要的解; 如本題首先我們可以把第一行第一列求出來非常簡單。 第一行就是用str1的第一個字元編輯成str2[j]所以就是i*ic 第一列就是用str2用str[i]的所有字元編輯成str2[0]所以就是i*dc dp[i][j]後面的就想辦法如何用之前的轉換而來,如下圖為了方便大家看我把dp打印出來 情況1: 以dp[3][2]來看假設已經到了3,2我們如何來進行得到這個最小代價呢,首先它的前面dp[i][j-1](j-1)是一樣的str1[0...i]組成了str2[0...j-1] 現在需要組成str2[0...j]個字元現在得到了str2[0...j-1]然後再加一個字元也就是加上str2[j]則就編輯成了str2[0....j]遞推式就是 dp[i][j]=dp[i][j-1]+ic 情況2:然後就是上面組成也就是可以由dp[i-1][j]也就是我可以用str1[0...i-1]編輯成str2[0....j] 然後再把現在的str1中的最後一個沒用到的刪除掉遞推表示式就是:dp[i][j]=dp[i-1][j]+dc 新增和刪除編譯代價都有了那麼我們來看一下修改替換的 替換會分兩種情況: 情況3:dp[i][j]與dp[i-1][j-1]的關係,當str1[i]==str2[j]時也就是最後一個字元已經匹配的上,也就是他前i-1和j-1個編輯的最小代價 就是現在dp[i][j]的代價;表示式也就是:dp[i][j]==dp[i-1][j-1](str1[i]==str2[j]) 情況4:顯而易見也就是當str1[i]!=str2[j]時也就是最後一個字元匹配不上那麼他就需要把str1[i]個替換成str2[j] 剩下的也就是和上面的情況一樣也就是str1[0...i-1]組成str2[0...j-1]的最小代價加上最後一個替換的代價就是這種情況的總得代價 表示式:dp[i][j]==dp[i-1][j-1]+rc(str1[i]!=str2[j]) dp: 0 5 10 15 20 3 0 5 10 15 6 3 2 7 12 9 6 5 4 9 12 9 6 7 6 15 12 9 6 9 18 15 12 9 8
public class DTGH_ChengeTwoString { public int chengeTwoString(String str1, String str2, int ic, int dc, int rc) { char[] str1s = str1.toCharArray(); char[] str2s = str2.toCharArray(); int m = str1s.length; int n = str2s.length; int[][] dp = new int[m][n]; for (int i = 0; i < m; i++) { dp[i][0] = i * dc; } for (int i = 0; i < n; i++) { dp[0][i] = i * ic; } for (int i = 1; i < m; i++) { for (int j = 1; j < n; j++) { int min1 = Math.min(dp[i - 1][j] + dc, dp[i][j - 1] + ic); if (str1s[i] == str2s[j]) { dp[i][j] = Math.min(min1, dp[i - 1][j - 1]); } else { dp[i][j] = Math.min(min1, dp[i - 1][j - 1] + rc); } } } //輸出矩陣 for (int i = 0; i <m ; i++) { for (int j = 0; j < n; j++) { System.out.print(dp[i][j]+" "); } System.out.println(); } return dp[dp.length - 1][dp[0].length - 1]; } public static void main(String[] args) { DTGH_ChengeTwoString a = new DTGH_ChengeTwoString(); System.out.println(a.chengeTwoString("ab12cd3", "abcdf", 5, 3, 2)); } }