趣味算法-04-跟着作者读《趣味算法(第2版)》-贪心算法

14天阅读挑战赛

努力是为了不平庸算法学习有些时候是枯燥的,这一次,让我们先人一步,趣学算法!

系列博客:

趣味算法-01-跟着作者读《趣味算法(第2版)》上
趣味算法-02-跟着作者读《趣味算法(第2版)》下
趣味算法-03-跟着作者读《趣味算法(第2版)》-算法之美
趣味算法-04-跟着作者读《趣味算法(第2版)》-贪心算法
本文是系列博客的第4篇,是听了陈老师的报告后的记录,主要包括如何学习算法。

算法知识点

贪心算法
一个贪心算法总是做出当前最好的选择,也就是说,它期望通过局部最优选择得到全局最优的解决方案。

对于贪心算法,需要注意以下几个问题:

  1. 一旦做出选择,就不可回溯
  2. 有可能得不到最优解
  3. 选择什么样的贪心策略直接决定算法的好坏

什么时候选择贪心算法:
满足贪心选择和最优子结构的问题

算法题目来源

《趣味算法第2版》

算法题目描述

海盗们截获一艘装满各种各样古董的货船,每一件古董都价值连城,但一旦打碎就会失去其原有的价值。海盗船虽然足够大,但载重量是有限的。海盗船的载重量为 W W W,每件古董的重量为 w i w_{i} wi,如何才能把尽可能多的古董装上海盗船呢?

做题思路

问题邀请装载的古董尽可能的多,在载重量有限的情况下,优先把重量下的古董装进去,装的最多,可以采用重量最小者优先装的贪心策略,从局部最优达到全局最优,得到最优装载问题的最优解。
采用重量最小最先装,然后每次从余下的古董中选择一个重量最小的古董。

  1. 如果采用顺序查找,第1次选择,需要比较 n n n次,第2次为 n − 1 n-1 n1次,总共需要比较 n ( n + 1 ) / 2 n(n+1)/2 n(n+1)/2次, 时间复杂度为 O ( n 2 ) O(n^{2}) O(n2)
  2. 如果采用快速排序,再按顺序选择,则时间复杂度为 O ( n log ⁡ n ) O\left(n \log n\right) O(nlogn)。相比顺序查找更优。

因此如果序列不变的情况下,先排序再选取更好

最终方案

  1. 先排序
  2. 根据贪心策略选择装入的古董

模板代码

# 假设最大载重为 30
W = 30
# 重量分布为
w = [4,10,7,11,3,5,14,2]

# 排序
w_new  = sorted(w)
print(w_new)
print("*"*10)
w_tmp = 0
w_in = []
for i in w_new:
    if (w_tmp < 30) and (w_tmp + i <30) :
        w_tmp = w_tmp + i
        w_in.append(i)
    else:
        w_tmp = w_tmp


print(w_in)
print("*"*10)
print(w_tmp)

输出为:

D:\ProgramData\Anaconda3\envs\py10\python.exe D:/pythonproject/chapter11/csdn博客/chapter02贪心算法.py
[2, 3, 4, 5, 7, 10, 11, 14]
**********
[2, 3, 4, 5, 7]
**********
21

在这里插入图片描述

做题过程中遇到的bug及解决方案

这个办法是最优的吗?其实对于本题是最优的,因为要求是获得最多的古董,那么一定是从小到大的古董最多,本体剩余9的载重量没有填满,也无法再填充更大的古董了。

有没有优化空间呢

针对这道题来说,排序部分可以优化下,采用Timsort排序可能会更好些
如果是背包问题,由于考虑最大价值,最小重量等多个问题,我们会提出对应的优化办法

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

IT从业者张某某

你的鼓励将是我创作的最大动力

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

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

打赏作者

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

抵扣说明:

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

余额充值