解題心得:
1、主要是找到狀態和狀態轉移方程,將大的問題縮小,一步步擴大得到最後的最優解。
2、和最長上公升子串行相比,此問題不過是單位長度1變成了硬幣的分值,所以將大於或小於改為value的幾個值
3、可以想推出前面幾項來得出最後的狀態轉移公式。
上面是在網上看到的一篇好文章,裡面有乙個湊硬幣的問題
如果我們有面值為1元、3元和5元的硬幣若干枚,如何用最少的硬幣湊夠11元? (表面上這道題可以用貪心演算法,但貪心演算法無法保證可以求出解,比如1元換成2元的時候)
首先我們思考乙個問題,如何用最少的硬幣湊夠i元(i<11)?為什麼要這麼問呢? 兩個原因:1.當我們遇到乙個大問題時,總是習慣把問題的規模變小,這樣便於分析討論。 2.這個規模變小後的問題和原來的問題是同質的,除了規模變小,其它的都是一樣的, 本質上它還是同乙個問題(規模變小後的問題其實是原問題的子問題)。
好了,讓我們從最小的i開始吧。當i=0,即我們需要多少個硬幣來湊夠0元。 由於1,3,5都大於0,即沒有比0小的幣值,因此湊夠0元我們最少需要0個硬幣。 (這個分析很傻是不是?別著急,這個思路有利於我們理清動態規劃究竟在做些什麼。) 這時候我們發現用乙個標記來表示這句「湊夠0元我們最少需要0個硬幣。」會比較方便, 如果一直用純文本來表述,不出一會兒你就會覺得很繞了。那麼, 我們用d(i)=j來表示湊夠i元最少需要j個硬幣。於是我們已經得到了d(0)=0, 表示湊夠0元最小需要0個硬幣。當i=1時,只有面值為1元的硬幣可用, 因此我們拿起乙個面值為1的硬幣,接下來只需要湊夠0元即可,而這個是已經知道答案的, 即d(0)=0。所以,d(1)=d(1-1)+1=d(0)+1=0+1=1。當i=2時, 仍然只有面值為1的硬幣可用,於是我拿起乙個面值為1的硬幣, 接下來我只需要再湊夠2-1=1元即可(記得要用最小的硬幣數量),而這個答案也已經知道了。 所以d(2)=d(2-1)+1=d(1)+1=1+1=2。一直到這裡,你都可能會覺得,好無聊, 感覺像做小學生的題目似的。因為我們一直都只能操作面值為1的硬幣!耐心點, 讓我們看看i=3時的情況。當i=3時,我們能用的硬幣就有兩種了:1元的和3元的( 5元的仍然沒用,因為你需要湊的數目是3元!5元太多了親)。 既然能用的硬幣有兩種,我就有兩種方案。如果我拿了乙個1元的硬幣,我的目標就變為了: 湊夠3-1=2元需要的最少硬幣數量。即d(3)=d(3-1)+1=d(2)+1=2+1=3。 這個方案說的是,我拿3個1元的硬幣;第二種方案是我拿起乙個3元的硬幣, 我的目標就變成:湊夠3-3=0元需要的最少硬幣數量。即d(3)=d(3-3)+1=d(0)+1=0+1=1. 這個方案說的是,我拿1個3元的硬幣。好了,這兩種方案哪種更優呢? 記得我們可是要用最少的硬幣數量來湊夠3元的。所以, 選擇d(3)=1,怎麼來的呢?具體是這樣得到的:d(3)=min。
ok,碼了這麼多字講具體的東西,讓我們來點抽象的。從以上的文字中, 我們要抽出動態規劃裡非常重要的兩個概念:狀態和狀態轉移方程。
上文中d(i)表示湊夠i元需要的最少硬幣數量,我們將它定義為該問題的」狀態」, 這個狀態是怎麼找出來的呢?我在另一篇文章 動態規劃之揹包問題(一)中寫過: 根據子問題定義狀態。你找到子問題,狀態也就浮出水面了。 最終我們要求解的問題,可以用這個狀態來表示:d(11),即湊夠11元最少需要多少個硬幣。 那狀態轉移方程是什麼呢?既然我們用d(i)表示狀態,那麼狀態轉移方程自然包含d(i), 上文中包含狀態d(i)的方程是:d(3)=min。沒錯, 它就是狀態轉移方程,描述狀態之間是如何轉移的。當然,我們要對它抽象一下,
d(i)=min,其中i-vj >=0,vj表示第j個硬幣的面值;
有了狀態和狀態轉移方程,這個問題基本上也就解決了。當然了,t**cheap,show me the code!**e co!e!
#includeusing namespace std;
int main()
; while(scanf("%d",&n)!=eof)}}
}
值改為2、3、5那麼不改變現在的狀態轉移方程會產生問題,d[4]將會等於1。究其原因是d[1]為0,d[4]可以由3+1組成,d[4]就變成了1.所以在平時寫狀態轉移方程時可以先手動推出幾項然後在依次推出。 動態規劃 硬幣問題
這是乙個固定重點的最長路和最短路問題,可用動態規劃問題來求解 代表硬幣總值,n代表硬幣總數,v陣列儲存硬幣各個面值,d代表從i出發到結點0的路徑的最長路徑長度或最短路徑長度 vis代表是否訪問過該結點 int n,s,v maxn d maxn vis maxn int dpmax int s re...
動態規劃 硬幣問題
2013 07 11 03 17 5610人閱讀收藏 舉報 演算法和資料結構學習 79 最少硬幣問題 假設有3種不同的硬幣,幣值分別是coinvalue 每一種硬幣的數量是有限的,分別是coinnum 給定乙個數值target 18,找出一種硬幣數最少的方法,輸出最少的硬幣數。思路 動態規劃。問題定...
動態規劃 硬幣問題
問題描述 輸入總金額n,硬幣不同價值的種類m,m種硬幣的面值 例如 15 6 1 2 7 8 12 50 輸出湊成n最少的硬幣數 1 貪心演算法 每次都選擇面值最大的。問題在於,求出來的並不是最優解,上例中,用貪心解出來的結果為3 1,2,12 而實際為2 7,8 include includeus...