贪心算法-01硬币找零问题

硬币找零问题

  • 前言
    • 所谓贪心算法,就是遵循某种既定原则,不断选取当前条件下最优的选择来构造每一个子步骤的解决方案,直到获得问题最终的求解。即在对问题求解时,总是做出在当前看来是最好的选择。也就是说,不从整体最优上加以考虑,所做的仅是在某种意义上的局部最优解。
    • 利用贪心算法,需要解决两个问题。
      • 一是问题是否适合使用贪心算法求解,即所求解问题是否具有贪心选择性质。所谓贪心选择性质,是指应用同一规则f,将原问题变为一个相似的但规模更小的子问题,后面的每一步都是当前看似最佳的选择。这种选择依赖于已做出的选择,但不依赖于未做出的选择。从全局上看,运用贪心策略解决的问题在程序的运行过程中无回溯过程。
      • 二是问题是否具有局部最优解,从而通过一个贪心标准,可以得到问题的最优解。
    • 利用贪心算法解题的思路一般为:
      • 建立对问题精确描述的数学模型,包括定义最优解的模型。
      • 将问题分解为一系列子问题,同时定义子问题的最优解结构。
      • 应用贪心算法原则可以确定每个子问题的局部最优解,并根据最优解模型,用子问题的局部最优解堆叠出全局最优解。
  • 问题描述
    • 对于给出的商店拥有的各种硬币的面值及其数目以及付款金额,如何计算使用最少硬币的方案?
  • 问题分析
    • 核心思想为消费者硬币数量有限,商店的硬币无限。因此,问题可以用如下公式描述:
      • min(消费者支付硬币数量+商店找零硬币数量)
      • 支付值-找零值=商品值
    • 可以理解为问题的求解就是上面两个问题的最优解。
    • 这里使用的贪心算法为max(消费者拥有的硬币面值-商店拥有的硬币面值)优先使用。
      • 例如消费者拥有面值2元的硬币,商店拥有5分的硬币,因此max=200-5=195。上面的组合情况为200,200-5,200-10,…,5。
      • 现在加入购买的商品是2元的,那么上面的组合中使用2元优先,只用一个硬币即可。假如商品是2元9角5分,上面的序列存在“100-5”的情况,这是能够使用的最大币值(贪心),就用它了,那么它是2枚硬币,即支付1元找零5分,共用了三枚硬币。
    • 验证算法的贪心选择性和最优子结构性质即可证明贪心算法可以得到最优解。
  • 代码
    •   # -*-coding:utf-8-*-
        
        d = [0.05, 0.1, 0.2, 0.5, 1, 2]
        d_sum = [2, 3, 4, 5, 6, 4]
        sum_value = 0
        for i in range(len(d)):
            sum_value += d_sum[i] * d[i]
        input_value = 2.5
        if input_value > sum_value:
            print("cannot change")
        else:
            i = 5
            while i >= 0:
                if input_value >= d[i]:
                    n = int(input_value/d[i])
                    if n >= d_sum[i]:
                        n = d_sum[i]
                    input_value -= n * d[i]
                    print("使用了{}个{:.2f}".format(n, d[i]))
                i -= 1
        
      
  • 运行结果
  • 补充说明
    • 具体代码可以查看我的Github,欢迎Star或者Fork
    • 参考书《你也能看得懂的Python算法书》
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

周先森爱吃素

你的鼓励是我坚持创作的不懈动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值