1.贪心算法
贪心算法又称为贪婪算法。贪心算法是指在对问题求解时,总能作出在此时此刻认为是最好的选择。也就是说,不从整体最优上加以考虑,只作出在某种意义上的局部最优解。它与动态规划算法相类似在于,最优解问题大部分都可以拆分成一个一个的子问题。贪心算法与动态规划算法不同之处在于,动态规划算法是得出整个问题的最优解,每次的结果会对未来的结果产生影响。而贪心算法每次的结果不会对未来的结果产生影响,只是考虑眼前的问题。贪心算法在解决问题的策略上目光短浅,仅仅依据当前已有的信息就作出选择,并且一旦作出了选择,无论将来有什么结果,这个选择都不会改变。例如,竭泽而渔就是把水放干之后捕鱼,这是一种不顾长远利益只顾眼前的贪心的行为。从某种意义上来看,贪心算法算是动态规划算法的一个特例。
2. 使用贪心算法
在超市找零钱是很正常的事情,通常他们会有各种面值的零钱,钱币面值有1毛、5毛、1元、5元、10元、20元、50元以及100元。当需要找顾客零钱时,零钱组合方式有很多种,本问题则要选择找出的钱币数目最少的方案。因此,本节需要解决的问题是当用户输入需要找的零钱数,找出的钱币个数最少的方案。
分析:尽可能多地选择面值较大的钱币,例如,用找零钱总金额80除以面值100,取商之后的整数是0,意味着100大于80,不能找面值为100元的钱币,依次类推。
实现找零钱问题的具体代码如下:
def change():
d = [0.01,0.02,0.05,0.1,0.2,0.5,1.0] # 存储每种硬币的面值
d_num = [] # 存储每种硬币的数量
s = 0
# 拥有的零钱总和
temp = input('请输入每种零钱的数量:')
d_num0 = temp.split(" ") # 用空格将每种零钱数量分割
for i in range(0, len(d_num0)): # 遍历每个空格
d_num.append(int(d_num0[i])) # 给存储硬币数量列表补充空格
s += d[i] * d_num[i] # 计算出收银员拥有多少钱
sum = float(input("请输入需要找的零钱:"))
if sum > s:
# 当输入的总金额比收银员的总金额多时,无法进行找零
print("数据有错")
return 0
s = s - sum # 收银员的总金额减去输入的总金额
# 要想用的钱币数量最少,那么需要利用所有面值大的钱币,因此从数组的面值大的元素开始遍历,贪心算法开始
i = 6 # 列表最大坐标
while i >= 0: # 循环找零
if sum >= d[i]: # 输入的总金额大于或等于每个零钱面值数,才进行找零
# 用输入的总金额从列表的最后一个元素开始整除取商,计算的是找每种面值的个数
n = int(sum / d[i])
if n >= d_num[i]: # 如果计算n大于或等于每个面值个数
n = d_num[i] # 更新n
sum -= n * d[i] # 贪心的关键步骤,令sum动态的改变
print("找了%d个%.2f元硬币"%(n, d[i])) # 输出需要找每种面值的情况
i -= 1 # 改变i的值用来结束循环
change() # 直接调用函数