JAVA 初識動態規劃

2021-09-21 18:30:48 字數 1745 閱讀 9578

動態規劃是為了解決遞迴呼叫佔記憶體、時間複雜度較大人的問題,而提出的一種程式設計思想。其中較為經典的,則是解決了斐波那契數列的低計算效率問題。

若是運用遞迴呼叫去求斐波那契數列的第n位數,則按照此方法,會將該位數根據公式,拆分成其他兩位數。而將其拆分出來的兩位數則會繼續被拆分為更小的兩位數,直到拆分到數列的開頭兩位已知數值的斐波那契數。可是,問題就在於,如果一直這樣拆分下去,原本早在樹的另一分支下被求出的數,因為沒有被儲存下來,以至於做著重複計算的低效率工作,大大拖延了程式執行時間。

到這裡,大家已經想到了問題的解決方法——將已經求過的數通過陣列儲存起來, 該方法被稱為備忘錄法

public class dp 

// if (n == 1)

// return f(n - 1) + f(n - 2);

// }

// o為2的n次方

// /**

// * 注: 動態規劃(備忘錄法)

// * 即即將原來的計算過的值儲存下來

// * 即傳乙個陣列進來

// * @param n

// * @return

// */

// public static int f(int n,int bak)

// if (n == 1)

//

// if(bak[n] !=-1)

//

//

// //若第n個值沒有求過,則

// int result=f(n - 1,bak) + f(n - 2,bak);

// //不要忘記將備忘錄也傳進去

//

// bak[n]=result;

// //曾經計算過的值將其存起來

//

// return result;

// }

/*** 注: 自底向上

* @param n

* @return

*/public static int f(int n)

if (n == 1)

// if(bak[n] !=-1)

//

//

// //若第n個值沒有求過,則

// int result=f(n - 1,bak) + f(n - 2,bak);

// //不要忘記將備忘錄也傳進去

//

// bak[n]=result;

// //曾經計算過的值將其存起來

// return result;

// }

// //雖然降低了複雜度,但用的仍是遞迴

int result=0;

int r1 =1;

int r2 =1;

for(int i=2;i<=n;i++)

return result;

} public static void main(string args)

// system.out.println(f(n,bak));

system.out.println(f(n));

}}

我們在這裡可以看出,該方法的注意點就在於——要將備忘錄傳進去,並且要給備忘錄裡的陣列初始化值為-1。這裡,乙個是要在數列的計算過程中將已經計算的值存入備忘錄中,另乙個則是要判斷我們所要求的數是否在數列之中。同時,返回值中判斷有了底n個數的值之後,也就不用再計算下去了。

動態規劃初識

適合用動態規劃的問題特徵 可以分解成相互重疊的若干子問題 滿足最優性原理 結構性質 該問題的最優解中也包含著其子問題的最優解。一般地,子問題的聯絡體現在某種遞推關係,通過這種遞推計算可以把問題的解儲存起來,後期直接使用,避免重複運算。簡單的dp例子 遞推關係 m i j m i 1 j m i j ...

初識動態規劃

有乙個矩陣map,它每個格仔有乙個權值。從左上角的格仔開始每次只能向右或者向下走,最後到達右下角的位置,路徑上所有的數字累加起來就是路徑和,返回所有的路徑中最小的路徑和。給定乙個矩陣map及它的行數n和列數m,請返回最小路徑和。保證行列數均小於等於100.輸入輸出樣例 第一行,輸入n,m表示這個矩陣...

初識動態規劃

let maxw 0 最大可放重量 let weight 2 2,4 6,3 物品重量 let n weight.length let w 11 揹包最大可承受重量 let men for let i 0 i n i men.push f 0,0 11 function f i,cw f i 1,c...