《程序员的算法趣题》-(日)增井敏克 , 书中为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]