昨天和前天写完了分治和dp,感觉收获真的挺大的,复习绝不是简单的重复记忆,而是将所学知识融会
贯通的过程,分析各种思想的异同,这些都是在平时学习和刷题的时候没有认真考虑的问题
好了,扯远了
今天分析一下到底什么叫贪心策略
怎么理解贪心:贪心在解决问题上是目光短浅的,仅仅根据当前的已知信息就做出选择,并且一旦做了选择,就不再更改
比如01背包问题,用贪心的话是不可解决的,因为贪心每次只顾眼前最优,即每次选择价值最大的,而忽
略了另外一个变量,物品的重量,如果还考虑物品的重量的话,那就是dp了
贪心和dp的联系是非常紧密的,我们先来分析一下贪心和dp的不同之处:
dp是根据迁移过程的状态去推导下一个过程的状态,是有理论依据的,是讲道理的,通过每次完美的检验
而得到最优解,关键是找最优子结构和重复子问题,书上一句原话:dp的子结构必须的独立的,而且是重
叠的,虽然有点矛盾,但确实是这样,扯远了
而贪心每次都只顾眼前最优,目光短浅,这种方式是不讲道理的,不想dp一样,还根据前面的迁移状态推
导后面的子问题,比如最经典的01背包问题(真的是理解dp和贪心的经典例题啊)
根据贪心策略,每次放进去的都是目前最优的,即目前价值最大的,直到背包装不下,但是这样放的话肯定
是不如人意的,因为没有考虑到背包容量的问题,为什么呢?因为前面说过了,贪心策略只考虑当前最优
解,它才不会去考虑什么背包容量的问题呢,它只管装价值最大的物品,这样是得不到最优解的,必须再加
一个约束条件:背包容量,那么这个做法就变成了dp的做法了
说的再多不如看几个例题,这样才能更好的体会贪心思想
经典样例一:最优装载问题
这个问题很容易,贪心策略就是每次装价值最大的物品即可,因为物品是不考虑重量和箱子容量的
这个问题我就是懒得贴代码了,实在是太容易了
这种贪心的策略一眼就能看出来,没有什么可以讲的,但是下面这个问题的贪心策略一眼可能是看不出来的
经典样例二:活动安排问题(属于安排策略,竞争某一公共资源问题)
活动安排问题就是要在所给的活动集合中选出最大的相容活动子集和
贪心策略:使得剩余的时间最大化,先安排最早结束的活动
为什么是这样呢?可能有朋友会觉得贪心策略应该是:先安排最早开始的活动,但是这样是不行的,你要是
这么贪心的话,如果一个活动是最先开始的,但是它的结束时间超级超级长,那你这样贪心的话,岂不是只
能安排它一个活动了吗?
所以我们要使得剩余的时间最大化,就是先安排最早结束的活动,因为你这个活动最早结束的话,你留给其
他活动的剩余的安排活动时间就最多呀,何况你还安排完了自己,一举两得,何乐而不为呢?
具体做法:每个活动是一个结构体:包含开始时间,结束时间,是否被安排过三个属性,按照结束时间升序
排序,每次都选择可以相容的,结束时间最早的活动(只有想到了贪心策略,代码还是很容易写的)
每次选取一个活动要考虑两个问题:结束时间是目前没有安排的活动中最早的,相容性
相容性:在安排了上一个活动的基础上,这个活动还能安排得进去,这个活动的开始时间大于或者等于上一个已经安排好的活动的结束时间
贴个代码:
#include<bits/stdc++.h>
using namespace std;
#define max_