牛客-美团 : 硬币兑换

题目描述

A 国一共发行了几种不同面值的硬币,分别是面值 1 元,2 元,5 元,10 元,20 元,50 元, 100 元。假设每种面值的硬币数量是无限的,现在你想用这些硬币凑出总面值为 n 的硬币, 同时你想让选出的硬币中,不同的面值种类尽可能多;在面值种类尽可能多的情况下,你想 让选择的硬币总数目尽可能多,请问应该怎么选择硬币呢?

输入描述:

第一行包含一个数字𝑛,表示要凑出的面值。1 ≤ 𝑛 ≤ 109

输出描述:

输出两个整数,分别表示最多能有多少种类型的硬币以及在类型最多的情况下最多能用上多少枚硬币。

示例1

输入

3

输出

2 2

解释

目标值是3, 需要1, 2两种硬币, 面值分别为1, 2共两个

示例2

输入

10

输出

3 5

解释

需要1, 2, 5三种面值, 硬币选择为 1, 1, 1, 2, 5共5枚。

代码

# 算法思想:
#   要求种类最多且数量最多。
#   种类最多时,我们需要尽量的先每一种硬币取一枚, 看能否满足条件,
#   数量最多时, 当我们每一种硬币娶一枚, 仍有剩余的, 就用面值为1的硬币填补, 就可以保证数目最多




target = int(input())

coins = [0, 1, 2, 5, 10, 20, 50, 100]

_sum = [0] * 10

# _sum 中每一个元素表示: 每一种硬币取一枚, 累加的和是多少, 目的是保证种类最多
# _sum = [0, 1, 3, 8, 18, 38, 88, 188]
#  表示,取面值为1的硬币1个, 面值总和为1
#       取面值为1, 2的硬币各一个, 两种硬币, 面值总和为3
#       面值为1, 2, 5 的硬币各一个, 三种硬币, 面值总和为5
#       .......
#  这样, 我们就知道,每一种硬币只取一个时, 面值总和是多少。
for i in range(1, len(coins)):
    _sum[i] = _sum[i-1] + coins[i]
    

# 从后往前查询
#  target = 100 为例:
#    首先我们应该先保证种类的数目,_sum数组从后往前查询,即先每种面值都先取一个, 取7种面值, 总和是188, 超过了100, 因此不选100面值的硬币
#    然后我们找_sum数组的倒数第二个位置,取6种面值的硬币各一个, 总和88, 小于100, 所以面值种类可以是6, 就是输出中的下标 i
#    下面确定硬币数目。 
#      6种面值各一个共88元, 已有i(这里是6)个硬币。 
#      还差(target-_sum[i])元, 这些面值全部用1元硬币填补, 需要 (target-_sum[i])个一元硬币。
#      最终总和是 i + (target-_sum[i]) 个硬币。
i = 7
while i >= 1:
    if target >= _sum[i]:
        print(i, target-_sum[i]+i)
        break
    i -= 1
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值