1. 算法思想:
動態規劃(dynamic programming)是運籌學的一個分支,是求解決策過程(decision process)最優化的數學方法。
動態規劃實際上是一類題目的總稱,並不是指某個固定的算法。動態規劃的意義就是通過採用遞推(或者分而治之)的策略,通過解決大問題的子問題從而解決整體的做法。動態規劃的核心思想是巧妙的將問題拆分成多個子問題,通過計算子問題而得到整體問題的解。而子問題又可以拆分成更多的子問題,從而用類似遞推迭代的方法解決要求的問題。
2. 應用場景:
適用動態規劃的問題必須滿足最優化原理、無後效性和重疊性。
1.最優化原理(最優子結構性質) 最優化原理可這樣闡述:一個最優化策略具有這樣的性質,不論過去狀態和決策如何,對前面的決策所形成的狀態而言,餘下的諸決策必須構成最優策略。簡而言之,一個最優化策略的子策略總是最優的。一個問題滿足最優化原理又稱其具有最優子結構性質。
2.無後效性 將各階段按照一定的次序排列好之後,對於某個給定的階段狀態,它以前各階段的狀態無法直接影響它未來的決策,而只能通過當前的這個狀態。換句話說,每個狀態都是過去歷史的一個完整總結。這就是無後向性,又稱爲無後效性。
3.子問題的重疊性 動態規劃將原來具有指數級時間複雜度的搜索算法改進成了具有多項式時間複雜度的算法。其中的關鍵在於解決冗餘,這是動態規劃算法的根本目的。動態規劃實質上是一種以空間換時間的技術,它在實現的過程中,不得不存儲產生過程中的各種狀態,所以它的空間複雜度要大於其它的算法。
3. 案例分析
題目:數塔
從上走到下,求經過的數字和的最大值
解題思路:
從底部開始,先通過小三角求解:
計算每一個小三角,經過的數字和的最大值。 並且將他們記錄下來,後面繼續使用
一直下去,直到計算到頂部。
....
代碼如下:
public class dp { public static void main(String[] args) { int[][] arr = { {7, 0, 0, 0, 0}, {3, 8, 0, 0, 0}, {8, 1, 0, 0, 0}, {2, 7, 4, 4, 0}, {4, 5, 2, 6, 5} }; System.out.println(new dp().maxSumNew(arr)); } /** * 動態規劃 * @param arr * @param * @return */ public int maxSumNew(int[][] arr) { if (arr == null) { return 0; } int n = arr.length; int[][] max = new int[n][n]; for (int i = n - 1; i >= 0; i--) { for (int j = 0; j <= i; j++) { if (i == n - 1) { max[n - 1][j] = arr[n - 1][j]; } else { max[i][j] = Math.max(max[i + 1][j], max[i + 1][j + 1]) + arr[i][j]; } } } return max[0][0]; } }
運行結果:
總結:最優化原理、無後效性和重疊性,有該特性的題目就可以考慮動態規劃。