動態規劃 解題4步曲

2021-10-09 05:23:35 字數 2545 閱讀 4075

以換硬幣問題來講解一下動態規劃解題4步曲:

你有三種硬幣,分別面值2元,5元和7元,每種硬幣都有足夠多。買一本書需要27元。不需要對方找錢,如何用最少的硬幣組合正好付清 ?

正常人第一反應思路:

最少硬幣組合?

優先使用大面值硬幣——7+7+7+5=26 額?可求解目標是27啊……

改演算法——7+7+7+2+2+2=27,總共用了6枚硬幣正好27元.

實際正確答案:7+5+5+5+5=27,才用了5枚硬幣。

所以這裡貪心演算法是不正確的。

動態規劃解題套路用起來。

狀態在動態規劃中的作用屬於定海神針。解動態規劃時需要開乙個陣列,這裡的「狀態」就是指數組的每個元素f[i]或f[i][j]代表什麼。

確定狀態需要兩個意識:最後一步和子問題

1.最後一步

這道題中,我們不知道最優策略是什麼,但最優策略肯定是k枚硬幣a1,a2……ak面值加起來是27。

這裡的「最後一步」就是存在最後一枚硬幣ak。

除去ak,前面的硬幣面值和為27-ak。

這裡有兩個關鍵點:

① 我們不關心前面的k-1枚硬幣是怎麼拼出27-ak的,我們也不知道ak和k,但是我們確定前面的硬幣拼出了27-ak。

② 因為是最優策略,所以拼出的27-ak硬幣數一定要最少,否則就不是最優策略。

2.子問題

現在問題變成了:最少用多少枚硬幣可以拼出27-ak。也就是將原問題(27)轉化成了乙個子問題,而且規模更小(27-ak)。

這種與原問題核心一致,但是規模更小的問題,就叫子問題。

為了簡化定義,我們設狀態f(x)=最少用多少枚硬幣拼出x。所以問題就從求f(x)變成求f(x-ak)

我們目前還不知道最後的硬幣ak面額多少,但它的面額一定只可能是2/5/7之一。

如果ak是2,f(27)應該是f(27-2) + 1 (加上最後這一枚面值2的硬幣)

如果ak是5,f(27)應該是f(27-5) + 1 (加上最後這一枚面值5的硬幣)

如果ak是7,f(27)應該是f(27-7) + 1 (加上最後這一枚面值7的硬幣)

除此以外,沒有其他的可能了。

因為要求最少的硬幣數,所以問題的解就可以這樣表示:

f(27) = min

設狀態f[x]=最少用多少枚硬幣拼出x

對於任意x,f[x] = min

如果正確列出轉移方程,問題基本就解決一半了。

大家基本也可以做到寫出狀態轉移方程,但真正寫程式的時候往往會出現很多錯誤或問題。

這就涉及到在在**前的兩個重要步驟,就是我們4步解題法的第三步和第四步。

f[x] = min的邊界情況是x-2, x-5或者x-7不能小於0(硬幣面值為正)

故對邊界情況設定如下:

如果硬幣面值不能組合出y,就定義f[y]=正無窮

例如f[-1]=f[-2]=…=正無窮;

f[1] =min=正無窮,表示拼不出1

特殊情況:本題的f[0]對應的情況為f[-2]、f[-5]、f[-7],按照上文的邊界情況設定結果是正無窮。

但是實際上f[0]的結果是存在的(即使用0個硬幣的情況下),f[0]=0。

這種用轉移方程無法計算,但是又實際存在的情況,就必須通過手動定義。

所以這裡定義初始條件為:f[0]=0.

而從0之後的數值是沒矛盾的,比如f[1]= f[1-2]+1= f[-1]+1=正無窮(正無窮加任何數結果還是正無窮);f[2]= f[2-2]+1= f[0]+1=1……

那麼開始計算時,是從f[1]、f[2]開始?還是從f[27]、f[26]開始呢?

判斷計算順序正確與否的原則是:

當我們要計算f[x](等式左邊,如f[10])的時候,等式右邊(f[x-2], f[x-5], f[x-7]等)都是已經得到結果的狀態,這個計算順序就是ok的。

實際就是從小到大的計算方式(偶有例外的情況我們後邊再講)。

例如我們算到f[12]的時候,發現f[11]、f[10]、f[9]都已經算過了,這種演算法就是對的;

而開始算f[27]的時候,發現f[26]還沒有算,這樣的順序就是錯的。

很顯然這樣的情況下寫乙個for迴圈就夠了。

回到這道題,採用動態規劃的演算法,每一步只嘗試三種硬幣,一共進行了27步。演算法時間複雜度(即需要進行的步數)為27*3。

原題練習:

這道題是lintcode 669:coin change

動態規劃解題4步曲

a)確定狀態

b)轉移方程

c)初始條件和邊界情況

d)計算順序

按照以上4步套路,基本上可以解決絕大多數型別的動態規劃題。

動態規劃解題思路

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

動態規劃解題思路

一直以來,對動態規劃的理解處於乙個模糊的狀態,就是一種似乎懂但遇到問題未必能行的狀態 然後,最近重點在leetcode上找了一些動態規劃的題目做了一下,逐漸有了一些思路。我覺得leetcode上對動態規劃思想的概括非常到位,所以記錄在這裡 動態規劃 英語 dynamic programming,簡稱...

動態規劃解題步驟

動態規劃解題步驟?給你兩個單詞 word1 和 word2,請你計算出將 word1 轉換成 word2 所使用的最少運算元 你可以對乙個單詞進行如下三種操作 插入乙個字元 刪除乙個字元 替換乙個字元 示例 1 輸入 word1 horse word2 ros 輸出 3 解釋 horse rorse...