接下來,讓我們來看看如何解決二維的dp問題。
問題描述:平面上有n*m個格仔,每個格仔中放著一定數量的蘋果。你從左上角的格仔開始,每一步只能向下走或是向右走,每次走到乙個格仔上就把格仔裡的蘋果收集起來,這樣下去,你最多能收集到多少個蘋果。
解這個問題與解其它的dp問題幾乎沒有什麼兩樣。第一步找到問題的「狀態」,第二步找到「狀態轉移方程」,然後基本上問題就解決了。
解這個問題與解其它的dp問題幾乎沒有什麼兩樣。第一步找到問題的「狀態」,第二步找到「狀態轉移方程」,然後基本上問題就解決了。
首先,我們要找到這個問題中的「狀態」是什麼?我們必須注意到的一點是,到達乙個格仔的方式最多只有兩種:從左邊來的(除了第一列)和從上邊來的(除了第一行)。因此為了求出到達當前格仔後最多能收集到多少個蘋果,我們就要先去考察那些能到達當前這個格仔的格仔,到達它們最多能收集到多少個蘋果。 (是不是有點繞,但這句話的本質其實是dp的關鍵:欲求問題的解,先要去求子問題的解)
經過上面的分析,很容易可以得出問題的狀態和狀態轉移方程。狀態s[i][j]表示我們走到(i, j)這個格仔時,最多能收集到多少個蘋果。那麼,狀態轉移方程如下:
s[i][j]=a[i][j] + max(s[i-1][j], if i>0 ; s[i][j-1], if j>0)
其中i代表行,j代表列,下標均從0開始;a[i][j]代**子(i, j)處的蘋果數量。
s[i][j]有兩種計算方式:1.對於每一行,從左向右計算,然後從上到下逐行處理;2. 對於每一列,從上到下計算,然後從左向右逐列處理。這樣做的目的是為了在計算s[i][j]時,s[i-1][j]和s[i][j-1]都已經計算出來了。
偽**如下:
這一節要討論的是帶有額外條件的dp問題。
以下的這個問題是個很好的例子。
無向圖g有n個結點,它的邊上帶有正的權重值。
你從結點1開始走,並且一開始的時候你身上帶有m元錢。如果你經過結點i,那麼你就要花掉s[i]元(可以把這想象為收過路費)。如果你沒有足夠的錢,就不能從那個結點經過。在這樣的限制條件下,找到從結點1到結點n的最短路徑。或者輸出該路徑不存在。如果存在多條最短路徑,那麼輸出花錢數量最少的那條。限制:
1
正如我們所看到的,如果沒有額外的限制條件(在結點處要收費,費用不足還不給過),那麼,這個問題就和經典的迪傑斯特拉問題一樣了(找到兩結點間的最短路徑)。
在經典的迪傑斯特拉問題中,我們使用乙個一維陣列來儲存從開始結點到每個結點的最短路徑的長度,即m[i]表示從開始結點到結點i的最短路徑的長度。然而在這個問題中,我們還要儲存我們身上剩餘多少錢這個資訊。因此,很自然的,我們將一維陣列擴充套件為二維陣列。m[i][j]表示從開始結點到結點i的最短路徑長度,且剩餘j元。通過這種方式,我們將這個問題規約到原始的路徑尋找問題。
在每一步中,對於已經找到的最短路徑,我們找到它所能到達的下乙個未標記狀態(i,j),將它標記為已訪問(之後不再訪問這個結點),並且在能到達這個結點的各個最短路徑中,找到加上當前邊權重值後最小值對應的路徑,即為該結點的最短路徑。 (寫起來真是繞,建議畫個圖就會明了很多)。
不斷重複上面的步驟,直到所有的結點都訪問到為止(這裡的訪問並不是要求我們要經過它,比如有個結點收費很高,你沒有足夠的錢去經過它,但你已經訪問過它) 最後min[n-1][j]中的最小值即是問題的答案(如果有多個最小值,即有多條最短路徑,那麼選擇j最大的那條路徑,即,使你剩餘錢數最多的最短路徑)。
偽**如下:
當閱讀乙個題目並且開始嘗試解決它時,首先看一下它的限制。如果要求在多項式時間內解決,那麼該問題就很可能要用dp來解。遇到這種情況,最重要的就是找到問題的「狀態」和「狀態轉移方程」。(狀態不是隨便定義的,一般定義完狀態,你要找到當前狀態是如何從前面的狀態得到的,即找到狀態轉移方程)如果看起來是個dp問題,但你卻無法定義出狀態,那麼試著將問題規約到乙個已知的dp問題。
動態規劃詳解
從一道題目出發 求兩個字串的最大公共子串長度,比如字串str1 bdcaba和字串str2 abcbdab的最大公共子串即為紅色部分bcba,長度為4 如何從動態規劃的思想出發解題呢,動態規劃的特點是當前最優解是從之前的子最優解和當前狀態分析得到,是一種遞推的過程,比如上述最大公共子串,對於長度為n...
動態規劃詳解
其實根本就談不上詳解,應該說只是隨便談談,真正能詳解動態規劃的又有幾個人,所以,這個標題略顯扯淡。前段時間一直在做關於資料結構的題,也算是對資料結構有了一定的了解,知道了有些資料結構的基本演算法。現在剛剛開始接觸動態規劃,其實寫這篇文章的初衷是一來鍛鍊一下自己的總結能力,二來也是希望通過這篇文章,來...
《動態規劃》 ACM 動態規劃例題詳解
描述 7 3 8 8 1 0 2 7 4 4 4 5 2 6 5 圖1 圖1給出了乙個數字三角形。從三角形的頂部到底部有很多條不同的路徑。對於每條路徑,把路徑上面的數加起來可以得到乙個和,你的任務就是找到最大的和。注意 路徑上的每一步只能從乙個數走到下一層上和它最近的左邊的那個數或者右邊的那個數。輸...