動態規劃現學現賣
阿新 • • 發佈:2019-01-05
動態規劃的兩種形式
自頂而下的備忘錄形式
自下而上的動態規劃
現在均使用Fib序列做個例子,具體程式碼和註釋如下圖:
/** * 動態規劃分為兩種: * 一種的是自下而上的動態規劃 * 一種是自上而下的備忘錄方法 * * @author jhc * */ public class FibTest { /** * 自下而上的備忘錄方法 * mem作為備忘錄一開始便建立一個空的一維陣列用來儲存各節點之間的值 * 這個還是用到了遞迴的方法 * */ public static int fibUpToBottom(int n,int[] mem){ if(mem[n] != -1){ return mem[n]; } if(n<=2){ return 1; }else{ mem[n] = fibUpToBottom(n-1,mem)+fibUpToBottom(n-2,mem); } return mem[n]; } /** * 上面的方法還是採用了遞迴的方法,我們可以自底而上的方法不用採用遞迴的方法 * @param n * @return */ public static int fibBottomToUp(int n){ int[] mem = new int[n+1]; mem[0] = 0; mem[1] = 1; mem[2] = 1; for(int i=3;i<=n;i++){ mem[i] = mem[i-1] + mem[i-2]; } // System.out.println("---"); // for(int i=0;i<=n;i++){ // System.out.print(mem[i]); // } // System.out.println(""); // System.out.println("----"); return mem[n]; } /** * 也可以不用一個數組來表示,因為實際上只用到了三個數字 */ public static int fibBottomToUpSimple(int n){ if(n <= 0) return n; int memI2 = 0; int memI1 = 1; int memI = 1; for(int i=2;i<=n;i++){ // System.out.print(memI+" "); /** * 注意先後順序的問題很重要容易搞錯 * */ memI = memI2 + memI1; memI2 = memI1; memI1 = memI; } return memI; } public static void main(String[] args){ int[] temp = new int[6]; for(int i=0;i<=5;i++){ temp[i] = -1; } System.out.println(fibUpToBottom(5,temp)); System.out.println(fibBottomToUpSimple(5)); System.out.println(fibBottomToUp(5)); } }
鋼條切割
package com.jhc.動態規劃解決.鋼條切割; /** * 自下向上的動態規劃演算法 * 用一個Solution陣列來儲存,而最優子結構為當前值要和前面所有的可能進行比較 * 我的做法是每次更新Solution * 利用Solution不斷去找到最適合我的值 找全所有的可能 * * @author jhc * */ public class Solution { private static int[] value = {0,1,5,8,9,10,17,17,20,24,30}; public static int mostValue(int n){ int[] solution = new int[n+1]; solution[1] = value[1]; for(int i=2;i<=n;i++){ solution[i] = value[i]; for(int j=1;j<i;j++){ solution[i] = Math.max(solution[i-j]+value[j],solution[i]); } } return solution[n]; } public static void main(String[] args){ System.out.println(mostValue(4)); } }