022.【贪心算法】

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()                                    				# 直接调用函数

猜你喜欢

转载自blog.csdn.net/qq_42226855/article/details/131258993