贪心算法的基本思想+任务安排问题、哈夫曼树、最小生成树算法(prim、kruskal)

什么是贪心算法

顾名思义,贪心算法是通过判断当前状态下看起来最好的结果,作为最好的结果。
一般来说,我们使用贪心算法的情况为需要一步步解决的问题,其中的每一个步骤都有一系列的选择,
比如01背包问题,我们有C容量的背包,上来就选择能装下的最大价值物品,然后对剩下容量继续上述操作。
(当然,如果知道的话,这种做法是错误的,我们将在后序给出讲解)

所以问题就来了,我们通过贪心算法一定能得到最优解吗?
还真不一定,我们需要进行证明,证明的关键点是优化子结构贪心选择性

优化子结构在dp问题中也是谈了很多次了,也就是整体最优是否能保证局部最优的问题,
这里我们要证明整体的最优解减去贪心的选择后剩下的部分仍为子问题的最优解。
(因为有子结构的存在,所以我们每一次的选择其实都可以通过第一步的证明类比出来。)

贪心选择性则需要强调一下,主要的落点还是选择,即我们选择的解是否一定在整体的最优解里面。

其实通过上面的例子和我们的分析,大约就能猜到dp和贪心之间有着千丝万缕的关系:

  • 首先吧,他们解决的问题都是存在子结构的,而且都需要保证子结构最优
  • dp说白了就是通过一个个的尝试,在最后给出一个最优解,
    而我们的贪心算法则是通过证明来给出一个选择方式,直接判断出哪一个选择是最优的,不需要比较,
    所以贪心是要比dp快很多的,但是需要一个证明。
  • 似乎看起来贪心能使用的情况下,dp都是成立的,其实很多问题确实如此,毕竟一次次比较也很难得不到最优解,但是对于最小生成树算法,比如prim和kruskal算法,这两个都是贪心算法,而dp的算法却很难给出。

任务安排问题

纸上谈兵终究很难抓住重点,我们先举一个例子,就是经典的任务安排问题。

定义

有一系列的任务,每一个任务都有开始和结束的时间,我们需要选择尽可能多但是不可以重叠的问题集。

既然是贪心算法,我们就需要有一个选择最优的判准,下面先给出几个

  1. 按照任务开始的时间,越早开始越好
  2. 按照任务结束的时间,越早结束越好
  3. 按照任务的时间长度,越短的越先开始。

这里我们直接给出答案,最早结束(或者最晚开始的活动也行)这一选择方式是可以证明的。

证明

贪心最重要的就是证明了,接下来我们看看应该怎么进行。

首先是优化子结构,我们还是采用反证法的方式。
我们贪心的选择是最早结束的活动a,最优解为S,那么X = S-a也一定为最优解。
(子结构为整体减去活动a)
如果不是最优解,那么我们就能找到另外一个X’,他比S‘的活动更多,当我们加上活动a时,很明显有:
X’+a > S’+a = S,而和S是最优解矛盾,所以子结构X一定最优,故得证。

然后是贪心选择性,也就是我的选择一定是在整体的最优解里面。
我们假设最优解为S,整个活动的最早结束活动为a,S中最早结束的活动为b
如果a == b,得证;
如果不等,因为a结束比b早,所以a和S-b一定没有交集,此时我们将b去掉,然后加上a,得到的S‘和S任务数相同,也为一个最优解,所以我们选择的a一定在一个最优解里面,得证。
(如果是最晚开始的活动也同理,这里不做证明&

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值