動態規劃解題思路

2021-10-04 14:44:00 字數 1913 閱讀 1718

一直以來,對動態規劃的理解處於乙個模糊的狀態,就是一種似乎懂但遇到問題未必能行的狀態……

然後,最近重點在leetcode上找了一些動態規劃的題目做了一下,逐漸有了一些思路。

我覺得leetcode上對動態規劃思想的概括非常到位,所以記錄在這裡

動態規劃(英語:dynamic programming,簡稱 dp)是一種在數學、管理科學、電腦科學、經濟學和生物資訊學中使用的,通過把原問題分解為相對簡單的子問題的方式求解複雜問題的方法。

動態規劃常常適用於有重疊子問題和最優子結構性質的問題,動態規劃方法所耗時間往往遠少於樸素解法。

動態規劃背後的基本思想非常簡單。大致上,若要解乙個給定問題,我們需要解其不同部分(即子問題),再根據子問題的解以得出原問題的解。動態規劃往往用於優化遞迴問題,例如斐波那契數列,如果運用遞迴的方式來求解會重複計算很多相同的子問題,利用動態規劃的思想可以減少計算量。

通常許多子問題非常相似,為此動態規劃法試圖僅僅解決每個子問題一次,具有天然剪枝的功能,從而減少計算量:一旦某個給定子問題的解已經算出,則將其記憶化儲存,以便下次需要同乙個子問題解之時直接查表。這種做法在重複子問題的數目關於輸入的規模呈指數增長時特別有用。

演算法課上老師也講到過:

(1)動態規劃和分治是非常像的,都是要把大問題分解成子問題,然後將子問題的解進行合併起來求原問題的解。

(2)動態規劃和分治的區別就是,分治的子問題之間一般不重複,動態規劃的子問題會有重複,而要把所有的子問題都列出來會是乙個非常複雜的問題。而在計算過程中通過記錄已經計算過的子問題的解,避免重複計算,這就是動態規劃進行剪枝的特點。

(3)動態規劃問題一般可以找到最優子結構(子問題)和遞迴子方程,通過這兩個條件,就可以得出動態規劃問題的解了。(遞迴子方程可以通過遞迴實現,也可以用迭代實現)

知乎上的這個回答也挺好:如何理解動態規劃? - 牛岱的回答 - 知乎

那麼,解動態規劃問題的一般方法是怎樣呢?

以前,我是想直接找到最優子結構,然後去找遞迴子方程。後來我覺得這種方法不合理,起碼是反常識的。

如果一開始我不知道這個問題是動態規劃問題,怎麼可以直接就去找最優子結構和遞迴方程呢?而且一些複雜的問題,很難直接找到最優子結構和遞迴方程。

(1)暴力法:先搞清楚問題想要得到的結果是什麼,先要得到這個結果,最直觀的方法是什麼?

一般這個方法的時間複雜度會比較高,中間會有很多的重複計算,不過沒關係,這個方案得出來,主要是將問題先解出來,後面再優化。

(2)動態規劃:在使用暴力法的解題過程中,我們基本上就能知道問題最終要求的是什麼,和要求得這個結果的所有子問題是什麼。

此時,我們可以去找子問題之間是否存在重複計算,而這種重複計算是否存在一種遞迴關係,比如斐波那契數列的f(i) + f(i+1) = f(i+2)。得到了遞迴方程,基本上這個問題就可以解出來了。

一般來說,乙個問題要轉化成數學問題/程式,需要有乙個合理的解釋,而有些問題比較複雜的時候,可以對其進行簡化或者加限定條件。比如給乙個長度為n的陣列,n太多了難以解決,可以先考慮乙個,然後兩個;或者把它分成左右兩半,看左半部分會不會做,右半部分會不會做。

再比如這個題,這個題需要判斷s和p是否匹配,一般兩個字串的匹配可以通過同時遍歷比對即可,但是這個題有萬用字元,尤其是*,使問題變得複雜。這時候,我們想到可以看單個字元是否匹配的方法,這很簡單,兩邊各取乙個字元比對即可。但是,問題來了,需要將s和p中的每個字元互相比對嗎?擴充套件成2個字元的時候怎麼也是要所有2個可能的字元嗎?在子問題的選擇上遇到了問題。這時可以回看一下問題,問題其實是判斷s的全部和p的全部是否匹配,我們在找子問題的時候不一定要找s的所有子字串和p的所有子字串,其實限定都是以s的結尾為結尾的子字串和以p的結尾為結尾的子字串進行比較,首先比對尾部,一點點擴充套件到索引為0的位置,就比較完了整個s和p字串,也就得到了結果。加了乙個一端固定的限定條件,就使思路瞬間清晰。

例項,絞盡腦汁做出的方案,有時候需要注意一些細節點,比如二叉搜尋樹的特點。。。

動態規劃解題思路

在leetcode上看題解與結合自己的想法得出思路。首先明確 dp 陣列所存資料的含義。這步很重要,如果不得當或者不夠清晰,會阻礙之後的步驟。然後根據 dp 陣列的定義,假設 dp 0 i 1 dp 0 i 1 都已知,想辦法求出 dp i dp i 一旦這一步完成,整個題目基本就解決了。但如果無法...

動態規劃解題一般思路

摘自mooc的程式設計與演算法 一.遞迴到動規的轉換方法 遞迴函式有n個引數,就定義乙個n維的陣列,陣列的下標就是遞迴函式引數的取值範圍,陣列元素的值就是遞迴的返回值,這樣就可以從邊界值開始逐步填充陣列,相當於計算遞迴函式值的逆過程 二.動態規劃解題一般思路 1.將原問題分解成子問題 把原問題分解成...

動態規劃解題的一般思路

遞迴到動規的一般轉化方法 遞迴函式有n個引數,就定義乙個n維的陣列,陣列的下表是遞迴函式引數的取值範圍,陣列元素的值是遞迴函式的返回值,這樣就可以從邊界值開始,逐步填充陣列,相當於計算遞迴函式值的逆過程 動規解題的一般思路 1.將原問題分解為子問題 把原問題分解為若干個子問題,子問題和原問題形式相同...