1、設計狀態變量
對於狀態變量的設計可以采取一維狀態變量dp[i]和二維狀態變量dp[i][0],dp[i][1]。
一維狀態變量需要考慮后效性問題。二維狀態變量相對於一維狀態變量通過增加維度來消除后效性。
例如:一維狀態變量dp[i]:區間 [0,i] 里接受預約請求的最大時長。
而二維狀態變量則表示了在i處的狀態:
dp[i][0]:區間 [0, i] 里接受預約請求,並且下標為 i 的這一天不接受預約的最大時長
dp[i][1]:區間 [0, i] 里接受預約請求,並且下標為 i 的這一天接受預約的最大時長
無后效性的理解:1、后面的決策不會影響到前面的決策; 2、之前的狀態怎么來的並不重要。
2、確定狀態轉移方程
3、初始化變量
4、考慮輸出
5、考慮是否可狀態壓縮
總結
「動態規划」告訴了我們另一種求解問題的思路。我們學習編程,習慣了自頂向下求解問題(遞歸),在自頂向下求解問題的過程中,發現了重復子問題,我們再加上緩存。而「動態規划」告訴我們,其實有一類問題我們可以從一個最簡單的情況開始考慮,通過逐步遞推,每一步都記住當前問題的答案,得到最終問題的答案,即「動態規划」告訴了我們「自底向上」思考問題的思路。
也就是說「動態規划」告訴我們的新的思路是:不是直接針對問題求解,由於我們找到了這個問題最開始的樣子,因此后面在求解的過程中,每一步都可以參考之前的結果(在處理最優化問題的時候,叫「最優子結構」),由於之前的結果有重復計算(「重復子問題」),因此必須記錄下來。
這種感覺不同於「記憶化遞歸」,「記憶化遞歸」是直接面對問題求解,遇到一個問題解決了以后,就記下來,隨時可能面對新問題。而「動態規划」由於我們發現了這個問題「最初」的樣子,因此每一步參考的以前的結果都是知道的,就像我們去考試,所有的考題我們都見過,並且已經計算出了答案一樣,我們只需要參考以前做題的答案,就能得到這一題的答案,這是「狀態轉移」。應用「最優子結構」是同一回事,即:綜合以前計算的結果,直接得到當前的最優值。
作者:liweiwei1419
鏈接:https://leetcode-cn.com/problems/the-masseuse-lcci/solution/dong-tai-gui-hua-by-liweiwei1419-8/
來源:力扣(LeetCode)
著作權歸作者所有。商業轉載請聯系作者獲得授權,非商業轉載請注明出處。
