帮助你理解贪心算法的小例子----选用最大面值支付

预备知识

贪心算法是指:在每一步求解的步骤中,它要求“贪婪”的 选择最佳操作,
并希望通过一系列的最优选择,能够产生一个问题的(全局的)最优解。

贪心算法每一步必须满足一下条件:
  1、可行的:即它必须满足问题的约束
  2、局部最优:他是当前步骤中 所有可行选择中最佳的局部选择
  3、不可取消:即选择一旦做出,在算法的后面步骤就不可改变了<一旦在当前选择某个方案,接下来就不可撤销该方案>

题目

实例1: 贪心算法实现钱币找零问题 假设1元、2元、5元、10元、20元、50元、100元的纸币分别有c0, c1, c2, c3, c4,c5, c6张。 现在要用这些钱来支付K元,至少要用多少张纸币?

CODE

注意:程序无法处理异常情况,当身上的钱没有足够的面额来支付

solution1

"""
用贪心算法的思想,很显然,每一步尽可能用面值大的纸币即可
"""
# 钱币面值从小到大排列好的
values = [1, 5, 10, 20, 50, 100]  # 钱币面值
counts = [4, 3, 2, 1, 4, 2]  # 钱币张数


# 计算找零 442 元时需要各种面值多少张
def change(money):
    values_ = values[::-1]  # 反转,倒序, 面值最大排在前面
    counts_ = counts[::-1]  # 反转,倒序
    result = []
    for index, value in enumerate(values_):
          # 需要最大面值人民币张数
        c = min(money//value, counts_[index])  # splendid
        # 计算剩余钱数
        money -= (c * value)
        result.append(c)
    return result[::-1]


if __name__ == '__main__':
    for i, v in enumerate(change(442)):
        if v:
            print('需要', v, '张', values[i] , ' 元')

solution2

for i in range(1, len(values)+1):
	# min()第一个参数加入int(),防止兑换的面额有 毛 单位,例如5毛钱
    c = min(int(money // values[-i]), counts[-i])
    if c:  # 判断钱币张数是否为0
        money -= c * values[-i]
    result.append(c)  # 最终可以使用zip函数绑定
if not money:
	return False # 身上的钱币不够 or 没有足够的面额
else:
	return result[::-1]

测试

0.5//0.5
1.0  # float
# 当剩余面额的张数可以完全抵扣时,这种方法不错
money %= v  

猜你喜欢

转载自blog.csdn.net/sinat_40701582/article/details/105843818