《程式設計師的演算法趣題》-(日)增井敏克 Python解題 -- (Q05)
《程式設計師的演算法趣題》-(日)增井敏克 , 書中為69 道數學謎題編寫了解題程式, 程式語言為:Ruby,JavaScript,C語言。有興趣的同學,可以購書閱讀~
在此更新個人編寫的Python版,僅供學習使用。(執行環境:Python3.6)
Q05 還在用現金支付嗎
當下,坐公交或者地鐵時大部分人都是刷卡的。不過,時至今日還在用現金支付的人還是比想象的多。本題我們以安置在公交上的零錢兌換機為背景。
這個機器可以用紙幣兌換到 10 日元、 50 日元、 100 日元和 500 日元硬幣的組合,且每種硬幣的數量都足夠多(因為公交接受的最小額度為 10 日元,所以不提供 1 日元和 5 日元的硬幣)。
兌換時,允許機器兌換出本次支付時用不到的硬幣。此外,因為在乘坐公交時,如果兌換出了大量的零錢會比較不便,所以只允許機器最多兌換出 15 枚硬幣。譬如用 1000 日元紙幣兌換時,就不能兌換出“100 枚 10 日元硬幣”的組合
問題
求兌換 1000 日元紙幣時會出現多少種組合?注意,不計硬幣兌出的先後順序。
def calc_money(money_bank, total_money, total_max_coin, out_combo=[]): if len(money_bank) == 0: return False res_money_bank = money_bank[1:] coin = money_bank[0] cur_max_coin = int(total_money / coin) total_result = [] if cur_max_coin > total_max_coin: cur_max_coin = total_max_coin for coin_count in range(cur_max_coin, -1, -1): cur_combo = [coin]*coin_count rest_money = total_money - coin*coin_count if rest_money == 0: total_result.append(out_combo+cur_combo) else: sub_calc = calc_money(res_money_bank, rest_money, total_max_coin-coin_count, out_combo+cur_combo) if sub_calc: total_result += sub_calc return total_result result = calc_money([500, 100, 50, 10], 1000, 15) print("共有%s種組合,分別為:\n%s" % (len(result), '\n'.join([str(sub) for sub in result])))
執行結果:
共有20種組合,分別為:
[500, 500]
[500, 100, 100, 100, 100, 100]
[500, 100, 100, 100, 100, 50, 50]
[500, 100, 100, 100, 100, 50, 10, 10, 10, 10, 10]
[500, 100, 100, 100, 100, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10]
[500, 100, 100, 100, 50, 50, 50, 50]
[500, 100, 100, 100, 50, 50, 50, 10, 10, 10, 10, 10]
[500, 100, 100, 50, 50, 50, 50, 50, 50]
[500, 100, 100, 50, 50, 50, 50, 50, 10, 10, 10, 10, 10]
[500, 100, 50, 50, 50, 50, 50, 50, 50, 50]
[500, 100, 50, 50, 50, 50, 50, 50, 50, 10, 10, 10, 10, 10]
[500, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50]
[500, 50, 50, 50, 50, 50, 50, 50, 50, 50, 10, 10, 10, 10, 10]
[100, 100, 100, 100, 100, 100, 100, 100, 100, 100]
[100, 100, 100, 100, 100, 100, 100, 100, 100, 50, 50]
[100, 100, 100, 100, 100, 100, 100, 100, 100, 50, 10, 10, 10, 10, 10]
[100, 100, 100, 100, 100, 100, 100, 100, 50, 50, 50, 50]
[100, 100, 100, 100, 100, 100, 100, 50, 50, 50, 50, 50, 50]
[100, 100, 100, 100, 100, 100, 50, 50, 50, 50, 50, 50, 50, 50]
[100, 100, 100, 100, 100, 50, 50, 50, 50, 50, 50, 50, 50, 50, 50]