1. 程式人生 > >《程式設計師的演算法趣題》-(日)增井敏克 Python解題 -- (Q05)

《程式設計師的演算法趣題》-(日)增井敏克 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]