動態(tài)規(guī)劃: 找零問題

動態(tài)規(guī)劃: 找零問題

問題描述


現(xiàn)實生活中經(jīng)常遇到找零錢的問題决采。假設(shè)去超市購物買了一個售價為3毛7分的商品自沧,你給售貨員1元(1元 = 100分)錢混卵,售貨員需要找錢給你酥夭。假設(shè)有四種面額的硬幣:1分、5分遮精、1毛移迫、5毛旺嬉,每種硬幣的數(shù)量充足。現(xiàn)在要求售貨員使用最少數(shù)量的硬幣厨埋, 求出這個最少數(shù)量是多少邪媳。
也就是求一個數(shù)63,可以由集合 {1 , 5 ,10 ,50 }中任意元素任意數(shù)量組成荡陷,求最少數(shù)量雨效。

求解思路


  • 思路一:根據(jù)日常生活經(jīng)驗,我們找零時候會從面額最大的開始湊废赞,如找63元徽龟,會先選擇50元,然后選10元唉地,最后選3個1元据悔。但這個方法并不能保證零錢的數(shù)量最少。例如耘沼,假設(shè)零錢面額為{1,20,50},需要找的是60极颓,按照剛才的方法,先選50群嗤,然后選10個1菠隆,零錢的數(shù)量為10。但是最優(yōu)解卻是選3個20。
  • 思路二:以上方法為貪心算法骇径,每次計算局部解只選擇一條路徑來計算躯肌。 為了求最優(yōu)解則會遍歷所有的計算路徑,因此使用動態(tài)規(guī)劃來求解比較合適既峡。

首先找出子問題羡榴。

例如為了湊足零錢63碧查,需要求解的子問題有 62(63 -1),58(63 -5) , 53(63 -10) 13(63 -50)的最少硬幣數(shù)量运敢。然后取其中最少的那個解。

需要找的零錢數(shù)量為amount , 硬幣面額為 coins {c1,c2,c3...cN }忠售。
最少硬幣數(shù)量遞推方程為 :

m(x) = min{m(x-ci)+1 } x-ci>=0
m(0) = 0
m(1) = 1

講完思路后上代碼传惠。

遞歸程序


使用遞歸來寫這個程序比較簡單。

  1. 找出遞歸基的臨界狀態(tài)稻扬。
  2. 利用剛才遞推方程遞歸調(diào)用選擇最優(yōu)解卦方。
 
def rec_min_coins(amount,coins):
    min_ret = amount
    if not coins:
        return 0
    if amount ==1:
        return 1    
    if amount <= 0:
        return 0
    else:       
        for  c in coins:
            if amount >= c:
                min_count = rec_min_coins(amount-c,coins)+1  
                if min_count < min_ret: #選出最小的結(jié)果
                    min_ret = min_count
                    
    return min_ret

values = [1,5,10,25]
import time
start = time.time()
print(rec_min_coins(63,values))

end = time.time()
print(end-start)         
out:6  104.87529873847961

運行遞歸程序耗費了104秒,中間一度還以為程序死循環(huán)了泰佳。
經(jīng)過分析以上程序時間復(fù)雜度為O(n)=4^n 也就是4^63盼砍,可想而知其性能是多么糟糕,下面通過動態(tài)規(guī)劃來優(yōu)化性能逝她。

動態(tài)規(guī)劃程序


用動態(tài)規(guī)劃方法浇坐,從狀態(tài)0開始計算并且把結(jié)果保存到一個數(shù)組里面,以避免子問題重復(fù)計算黔宛。

 def dp_min_coins(amount,coins):
    mins  = [0 for x in range(amount+1)]
    for i  in  range(1,amount+1):
        min_ret = i
        for c in coins:
            if i >=c:
                min_count =mins[i-c]+1
                if min_count < min_ret:
                    min_ret = min_count 
        mins[i] = min_ret
    return mins[amount]

values = [1,5,10,25]
import time
start = time.time()
print(dp_min_coins(63,values))
end = time.time()
print(end-start)   
out:6
0.0010821819305419922

可以看到動態(tài)規(guī)劃運行時間不到1秒近刘。

總結(jié)


遇到求最優(yōu)解問題時,通惩位危可以用動態(tài)規(guī)劃或者遞歸來求解觉渴。但由于遞歸法求解過程中需要計算大量重復(fù)的子問題 ,其時間復(fù)雜度 O(n)=C^n徽惋。因此往往會優(yōu)先采用性能更好的動態(tài)規(guī)劃法案淋。

參考


DPChange

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市险绘,隨后出現(xiàn)的幾起案子踢京,更是在濱河造成了極大的恐慌,老刑警劉巖隆圆,帶你破解...
    沈念sama閱讀 218,284評論 6 506
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件漱挚,死亡現(xiàn)場離奇詭異,居然都是意外死亡渺氧,警方通過查閱死者的電腦和手機旨涝,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,115評論 3 395
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人白华,你說我怎么就攤上這事慨默。” “怎么了弧腥?”我有些...
    開封第一講書人閱讀 164,614評論 0 354
  • 文/不壞的土叔 我叫張陵厦取,是天一觀的道長。 經(jīng)常有香客問我管搪,道長虾攻,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 58,671評論 1 293
  • 正文 為了忘掉前任更鲁,我火速辦了婚禮霎箍,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘澡为。我一直安慰自己漂坏,他們只是感情好,可當我...
    茶點故事閱讀 67,699評論 6 392
  • 文/花漫 我一把揭開白布媒至。 她就那樣靜靜地躺著顶别,像睡著了一般。 火紅的嫁衣襯著肌膚如雪拒啰。 梳的紋絲不亂的頭發(fā)上驯绎,一...
    開封第一講書人閱讀 51,562評論 1 305
  • 那天,我揣著相機與錄音图呢,去河邊找鬼条篷。 笑死,一個胖子當著我的面吹牛蛤织,可吹牛的內(nèi)容都是我干的赴叹。 我是一名探鬼主播,決...
    沈念sama閱讀 40,309評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼指蚜,長吁一口氣:“原來是場噩夢啊……” “哼乞巧!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起摊鸡,我...
    開封第一講書人閱讀 39,223評論 0 276
  • 序言:老撾萬榮一對情侶失蹤绽媒,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后免猾,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體是辕,經(jīng)...
    沈念sama閱讀 45,668評論 1 314
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,859評論 3 336
  • 正文 我和宋清朗相戀三年猎提,在試婚紗的時候發(fā)現(xiàn)自己被綠了获三。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 39,981評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖疙教,靈堂內(nèi)的尸體忽然破棺而出棺聊,到底是詐尸還是另有隱情,我是刑警寧澤贞谓,帶...
    沈念sama閱讀 35,705評論 5 347
  • 正文 年R本政府宣布限佩,位于F島的核電站,受9級特大地震影響裸弦,放射性物質(zhì)發(fā)生泄漏祟同。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 41,310評論 3 330
  • 文/蒙蒙 一烁兰、第九天 我趴在偏房一處隱蔽的房頂上張望耐亏。 院中可真熱鬧徊都,春花似錦沪斟、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,904評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至李根,卻和暖如春槽奕,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背房轿。 一陣腳步聲響...
    開封第一講書人閱讀 33,023評論 1 270
  • 我被黑心中介騙來泰國打工粤攒, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人囱持。 一個月前我還...
    沈念sama閱讀 48,146評論 3 370
  • 正文 我出身青樓夯接,卻偏偏與公主長得像,于是被迫代替她去往敵國和親纷妆。 傳聞我的和親對象是個殘疾皇子盔几,可洞房花燭夜當晚...
    茶點故事閱讀 44,933評論 2 355

推薦閱讀更多精彩內(nèi)容