寫在前面,一定要弄清楚,字典的傳遞傳的是引用,是位址!,這個小問題浪費了我將近兩個小時。等號複製,dict.copy()和copy模組的deepcopy()方法,這三個要搞清楚。前面提到了遞迴方法解決找零問題,但是當數值非常大,或者紙幣面值種類很多時,程式跑起來就會花費很多時間。我的筆記本配置比較低,面值[1,5,10,25]的,找零63元,需要5分鐘所有的時間。其實可以想象,這種遞迴非常浪費時間。
可以在計算的過程中儲存子問題的最優解,需要用到的時候先查表,有則取出來,無則計算並存表。
這裡我用了兩個表,乙個是儲存紙幣數量,另乙個是儲存對應數量的紙幣方案字典。(一定要注意,字典傳遞的是引用,對字典進行修改時需要「複製」乙份)
def recmc(coinlist, change, knowresults, knowdics):
dic = {}
dics = {}
mincoins = change
# coinlist.sort(reverse=true)
# 遞迴終止條件
if change in coinlist:
# if dic.get(str(change)):
# dic[str(change)] += 1
# else:
dic[str(change)] = 1
# 將最優解的數值記入列表,下標即為面值
# 將最優解的字典(方案)記入列表,值為字典引用
knowresults[change] = 1
knowdics[change] = dic
return 1, dic
# 向遞迴終止演進
# 看是否已經計算過這個最優解
elif knowresults[change] > 0:
return knowresults[change], knowdics[change]
# 不存在則計算
else:
for c in [i for i in coinlist if i <= change]:
num, dicc = recmc(coinlist, change - c, knowresults, knowdics)
# 因為後續要修改,其實就是大規模問題用到了子問題的字典,注意要複製。不能單純的等號賦值,這依舊是傳的是引用。
# dic = dicc.copy()
dic = copy.deepcopy(dicc)
numcoins = 1 + num
if dic.get(str(c)):
dic[str(c)] += 1
else:
dic[str(c)] = 1
if numcoins <= mincoins:
mincoins = numcoins
dics = dic
# 找到最小值,並儲存入錶
knowresults[change] = mincoins
knowdics[change] = dic
# print(type(dic))
return mincoins, dics
import time
import copy
print(time.clock())
num, dic = recmc([1,5,10,25], 63, [0]*64, [0]*64)
# num, dic = recmc([1], 63, [0]*64, [0]*64)
print(num)
print(dic)
print(time.clock())
最終只需要不到一秒的時間就能夠計算出來,大大減少了時間開銷。 找零問題求解
今天我們來分享乙個大家都喜聞樂見的問題 找零問題。為什麼說會喜聞樂見呢?這不想多了嘛,都跟你談錢了,還需要多說什麼嗎。說到錢,我們就不說閒話了,直接來看下今天的分享內容吧。首先來看如何使用貪心演算法來求解。以及何時可以使用貪心演算法求解。栗子?假設當前有1 2 5 10 20 50 100等面額的紙...
找零問題之貪心演算法求解Python
貪心演算法是基於區域性最優原理,將問題分割成若干個小的子問題,然後求解子問題的最優解,這樣歸併子問題的解,從而求得整個問題的解。當然這個解並不是最優解,只能說是近似最優解,因為區域性最優的合併並不一定是全域性最優。貪心演算法還有驗證解的步驟,這個比較簡單,就是把解帶入即可 找零問題,比如說售貨員需要...
動態規劃演算法求解硬幣找零問題
1.問題描述 現存在一堆面值為 v1 v2 v3 個單位的硬幣,問最少需要多少個硬幣才能找出總值為 t 個單位的零錢?假設這一堆面值分別為 1 2 5 21 25 元,需要找出總值 t 為 63 元的零錢。2.分析 動態規劃的基本思想是將待求解問題分解成若干個子問題,先求解子問題,並將這些子問題的解...