【Python】(十二)從自動販賣機找零看Python中的動態規劃問題
問題描述
假設在某國存在[1,x1,x2,x3,...,xn]多種貨幣,該國的自動販賣機在找零時要遵循一個原則——“找零的總張數最少”。那麼,該如何編寫程式,幫助自動販賣機自動找零呢?
問題分析
解決這一問題的最直接思路是窮舉法。假設需要找零Y元,那麼就通過所有的小於Y的貨幣,列舉出找零的所有方案,進而比較哪個總張數最少。這種思路需要在計算中蘊含有大量的重複,時間複雜度極大。
類似問題的一個有效解法是使用動態規劃的思想來處理。
求解找零所需要最少貨幣數
以面值為1,5,10,25的貨幣為例:
解決這一問題的關鍵在於,利用類似的等式,不斷縮小問題的規模。當問題縮小為“需要多少張貨幣來找0元”時,問題的答案顯然是0。
我們需要額外做的就是建立一個列表,用以儲存比要計算的找零需求更小的需求。
# need_change 為需要找零的金額,
# currency_list 為該國貨幣的面值列表,
# num_list 為需要找零的最少貨幣數目, num_list的長度至少為(need_change+1)
def giveChange(need_change, currency_list, num_list):
for change in range(need_change+1): #從0開始計算最少需要的貨幣數
for currency in currency_list: #遍歷每一種貨幣
if (change-currency >= 0) and (num_list[change-currency]+1<num_list[change]): #計算最少貨幣需求數
num_list[change] = num_list[change-currency] + 1
return
def main():
need_change = 63
currency_list = [1,5,10,21,25]
num_list = list(range(need_change+1)) #初始化num_list為0到need_change,共(need_change+1)個數
giveChange(need_change, currency_list, num_list)
print("%d 需要 %d 個貨幣來找零"%(need_change, num_list[need_change]))
if __name__ == "__main__":
main()
執行結果為:
63 需要 3 個貨幣來找零
僅僅輸出了正確的貨幣數目是不夠的,我們還需要輸出具體是哪些面值的貨幣。
自動找零問題的解決
如同常見的,最短路徑的記錄一樣。為輸出具體是需要找哪些面值的貨幣的零錢,我們需要再上一步驟的基礎上記錄下每步求解最小化使用的貨幣。
為此,我們需要在新增一個列表,用以記錄這個數值。
# need_change 為需要找零的金額,
# currency_list 為該國貨幣的面值列表,
# num_list 為需要找零的最少貨幣數目, num_list的長度至少為(need_change+1)
# used_list 為需要找零的最少貨幣數目, 長度與num_list相同
def giveChange(need_change, currency_list, num_list, used_list):
for change in range(need_change+1): #從0開始計算最少需要的貨幣數
for currency in currency_list: #遍歷每一種貨幣
if (change-currency >= 0) and (num_list[change-currency]+1<=num_list[change]): #計算最少貨幣需求數
num_list[change] = num_list[change-currency] + 1
used_list[change] = currency #記錄消耗的貨幣
return
# 返回需要的貨幣
def showChange(need_change, used_list):
give_list = []
while need_change > 0:
give_list.append(used_list[need_change])
need_change -= used_list[need_change]
give_list.sort() #排序
return give_list
def main():
need_change = 64 #需要找零的錢數
currency_list = [1,5,10,21,25] # 該國的貨幣面值列表
num_list = list(range(need_change+1)) #初始化num_list為0到need_change,共(need_change+1)個數
used_list = list(range(need_change+1)) #初始化used_list為0到need_change,共(need_change+1)個數
giveChange(need_change, currency_list, num_list, used_list)
print("%d 需要 %d 個貨幣來找零"%(need_change, num_list[need_change]))
give_list = showChange(need_change, used_list)
print(give_list)
if __name__ == "__main__":
main()
計算結果為:
64 需要 4 個貨幣來找零
[1, 21, 21, 21]
相關文章
- 找零問題與動態規劃動態規劃
- 動態規劃5:找零錢問題動態規劃
- 使用動態規劃完美解決硬幣找零問題(Python)動態規劃Python
- 矩陣連乘問題 Python 動態規劃矩陣Python動態規劃
- 詳解動態規劃最少硬幣找零問題–JavaScript實現動態規劃JavaScript
- 詳解動態規劃最少硬幣找零問題--JavaScript實現動態規劃JavaScript
- 動態規劃系列之九找零錢動態規劃
- 演算法系列-動態規劃(3):找零錢、走方格問題演算法動態規劃
- 買賣股票相關演算法-動態規劃-python演算法動態規劃Python
- 【動態規劃】買賣股票動態規劃
- 從“股票問題”談動態規劃問題的解決思路動態規劃
- 動態規劃之子序列問題動態規劃
- 揹包問題----動態規劃動態規劃
- 【動態規劃】揹包問題動態規劃
- 整數劃分問題(動態規劃)動態規劃
- Python演算法:動態規劃Python演算法動態規劃
- python 動態規劃(揹包問題和最長公共子串)Python動態規劃
- Python動態規劃實現虛擬機器部署Python動態規劃虛擬機
- 動態規劃 01揹包問題動態規劃
- 【動態規劃】01揹包問題動態規劃
- 動態規劃-01揹包問題動態規劃
- 動態規劃,股票問題留坑動態規劃
- 動態規劃篇——揹包問題動態規劃
- 醜數問題——動態規劃、Java動態規劃Java
- (動態規劃)最小分糖果問題動態規劃
- 動態規劃--01揹包問題動態規劃
- 動態規劃用於解決重疊子問題的示例(Python版)動態規劃Python
- 動態規劃9:變態跳臺問題動態規劃
- 好題——動態規劃動態規劃
- 動態規劃專題動態規劃
- 動態規劃題單動態規劃
- 【動態規劃】01揹包問題【續】動態規劃
- 一維動態規劃和二維動態規劃中兩道經典題目動態規劃
- 我的動態規劃題單動態規劃
- 【演算法】找零錢-動態規劃實現過程解析演算法動態規劃
- “插花問題”的動態規劃法演算法動態規劃演算法
- 插花問題的“動態規劃法”演算法動態規劃演算法
- 【動態規劃(一)】動態規劃基礎動態規劃