Python数据结构18:找零问题的贪心算法代码,优化问题,解决优化问题的贪心策略

1.优化问题

优化问题就是为了找到某些问题的最优解
最优:比如两个点之间有许多路径,找到最短的路径。
一个典型的优化问题:兑换最少硬币问题。就是当自动售货机找零的时候,每次找给顾客最少数量的硬币。
如果不是做最优解的话,就比较简单,就每次只找给1毛钱就行了。当然,很多人不能接受。

下面看一个实例:
假设你为一家自动售货机厂家编程序,自动售货
机要每次找给顾客最少数量硬币;假设某次顾客投进$1(1美元)纸币,买了ȼ37(37美分)的东西,要找ȼ63,那么最少数量就是:2个quarter(ȼ25)、1个dime(ȼ10)和3个penny(ȼ1),一共6个硬币。

2.贪心策略Greedy Method

人们在解决上述的这些问题的时候,发现最直观的还是贪心策略。

从最大面值的硬币开始,用尽量多的数量。有余额的时候(例如用了2个25美分,还剩下13美分,不足以再用一个25美分),再到下一最大面值的硬币,还用尽量多的数量,一直到penny(ȼ1,即最小的面额)为止。

贪心策略就是每次都试着解决问题的最大的一部分。
因为我们每次都试图解决问题的尽量大的一部分。对应到兑换硬币问题,就是每次以最多数量最大面值硬币来迅速减少找零面值。
在现实生活中,贪心策略确实是解决大多数硬币找零问题的有效方法。贪心策略是我们能想到的最直观有效的方法,反过来,也可以说,货币的面值就是按照贪心策略来设计的。

代码如下:

# 假设最大的面值是1美元,售货机的货物价格都低于1美元,可以找零的面值有25美分,10美分和1美分。
changes = [25, 10, 1]
input_money = 100  # 投入到售货机里面的是1美元,即100美分
print('Please enter the price of the item you selected:')
selection = int(input())
change = input_money - selection
count = 0  # count 用于计算硬币的个数
for i in changes:  # 从最大的面值依次向小面值找钱
    while change >= 0:  # 当要找的零钱数大于当前面值时
        change = change - i  # 计算找零后是否大于0,如果找零0大于0就代表还有可能继续用这个面值找钱,否则就要换下一个小面值了
        if change >= 0:  # 该面值找零后大于0,使用一个该面值的硬币
            count = count + 1
        else:  # 该面值找零后小于0,需要使用下一个面值的硬币,把需要找零的钱还原,跳出循环,进入下一个面值
            change = change + i
            break
print("The amount of change is %d" % count)

3. 贪心策略失效的情况

在一个漫画中,有一个杜撰的国家叫做(ELbonia),这个古怪的国家,除了有25美分,10美分和1美分以外,还有一种21美分ȼ21的硬币。

在这个国家贪心策略就失效了,如果使用原来的贪心策略,
63 = 25 * 2 + 10 * 1 + 1 * 3 , 共 2 + 1 + 3 = 6枚硬币
但是最优的策略是,
63 = 21 * 3,共 3 枚硬币。
因此贪心策略严重依赖于货币的币值设计。

参考

本文的知识来源于B站视频 【慕课+课堂实录】数据结构与算法Python版-北京大学-陈斌-字幕校对-【完结!】,是对陈斌老师课程的复习总结
代码是我自己写的,功能比较简单

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值