動態規劃學習總結

2021-07-26 23:11:31 字數 1127 閱讀 1202

動態規劃(dp)是一種用途很廣的問題求解方法,他本身並不是乙個特定的演算法,而是一種思想,一種手段。對於乙個問題,先處理一部分,剩下來的部分和原問題的處理方式或者說性質相同,這樣就可以再次從該部分中分出一部分進行處理,如此反覆,便可以得到問題的完整解答。

動態規劃的核心是狀態轉移方程,即描述問題的當前狀態和處理後的狀態之間的關係的乙個或多個等式(有些問題在不同的情況下可能需要不同的處理方式)。

在一些資料的遍歷中(如不重複的路徑搜尋問題),為了標記哪些點已經走過,可能需要重新建立乙個陣列來記錄路徑。這樣十分浪費時間和空間,而我們實際上可以直接對原陣列進行處理,用特定的數字表示已走過或沒有走過,這樣方便查詢也節省空間。

有乙個由非負整數組成的三角形,第一行只有乙個數,除了最下行之外每個數的左下方和右下方各有乙個》數,如圖所示:

從第一行的數開始,每次可以往左下或右下走一格,直到走到最下一行,把沿途經過的數全部加起來。如何走才能使得這個和最大?

初看之下可能覺得這是乙個貪心問題,但實際上這裡面包含了dp的核心思想。為了得到高效的演算法,需要用抽象的方法思考問題:把當前位置(i,j)看成乙個狀態,d(i,j)表示從格仔出發時能得到的最大和。則原問題的解為d(1,1)(從每個格仔開始的路徑均可以看做是原問題的子問題,即 d(1,1) = max等)。

則在該定義下,狀態轉移方程為d(i,j) = a(i,j) + max

再加入記憶化搜尋的方法:如果只是暴力地遍歷所有格仔,則一定會重複走過大量的路徑,浪費很多時間,這時候就可以使用記憶化搜尋:使用memset()將d陣列(結果記錄陣列)中所有的值初始化為-1(或者其他任意不會與結果衝突的標記),這樣,當計算過乙個格仔後,其元素就會自動變成結果的值。

memset(d,-1,sizeof(d));

int solve (int i,int j)

這裡有個細節:如果要自上而下的計算的話就必須使用遞迴,這樣會占用許多記憶體,而如果使用反向遍歷(即自下而上)就可以直接使用迴圈處理,因為計算上層所需要的元素在之前已經計算好了。

動態規劃學習總結

1.有時候階段劃分不正確,導致不是最優解。2.邊界條件找錯,或資料開的小,導致超時或wrong answer等。3.初始化出錯,不是所有的初始化都是為0,有的是其他的,eg memset a,127,sizeof a 這要根據題目具體分析。4.揹包問題有時半天推不出是什麼型別的揹包問題。5.揹包問題...

動態規劃總結

華電北風吹 天津大學認知計算與應用重點實驗室 日期 2015 12 7 近期學了幾個動態規劃正好總結一下。裡面不涉及具體問題的具體解法,有問題可以參看我的具體型別的講解部落格。目前所見動態規劃可以劃分為兩類 鏈式和樹形。而且這兩類中的每個節點都是乙個完整的狀態集合。一 鏈式動態規劃 鏈式動態規劃的題...

動態規劃 總結

動態規劃是解決多階段決策問題的一種方法。如果一類問題的求解過程可以分為若干個互相聯絡的階段,在每乙個階段都需作出決策,並影響到下乙個階段的決策,從而確定了乙個過程的活動路線,則稱它為多階段決策問題。思想 在做每一步決策時,列出各種可能的區域性,解依據某種判定條件,捨棄那些肯定不能得到最優解的區域性解...