一、什么是贪心
贪心算法嘛、、、
就是在对某个问题求解时,总是做出在当前看来是最好的选择
In other wors,并不是从整体最优上加以考虑,而是在获得某种意义上的局部最优解
二、贪心算法的适用前提
局部的最优解能导致最后整体的最优解,即局部的最优解不受该部分以外的东西的影响
对于贪心算法,我们需要证明:整个问题的最优解一定由在贪心策略中存在的子问题的最优解得来的
实际上,能用贪心算法的问题很少,大部分看上去能用贪心算法去做的题目,其实都得不到最优解T T(这时候就需要运用动态规划了)
而看上去不能贪心的问题经过转化,反而可以运用贪心求解(额这个…)
三、贪心算法的基本思路:
(1)问题转化
(2)把求解的问题分成若干个子问题
(3)对每一子问题求解,得到子问题的局部最优解
(4)把子问题的解局部最优解合成原来解问题的一个解
↑上面那些@#%^*¥…&*#¥%@是不是太烦了。。。谁不懂”贪心”这两个字啊≥v≤~
所以在实际问题中进行分析即可!
(概括为两句话:贪心算法就是按照字面意思求局部最优;但局部最优不一定是整体最优,故需要证明成立)
四、简单贪心算法例题
BZOJ1689 [Usaco2005 Open] Muddy roads 泥泞的路
给一个长度为N的格子,一些格子有水。现在有长度为L的东西(比如,木板)覆盖,问至少要用几木板才能把水坑都盖住。
解法是:每个木板在当前满足条件的情况下尽量往后放。
证明:假设当前i有水,i-1没有水,因为长度是固定的,那么显然从i放,由于从i-1放木板有可能会少盖住一个后面的水池。
于是模拟怎么放木板即可。
另两题:
BZOJ2014 [Usaco2010 Feb]Chocolate Buying
BZOJ3544 [ONTAK2010]Creative Accounting
五、进阶版贪心算法例题
BZOJ1658 [Usaco2006 Mar]Water Slides 滑水
一维坐标轴上有n个点,有些点之间有单向滑梯,现在要滑完所有滑梯仅一次,问走的路最少的解法。(n = 10000)
一开始建立的是网络流模型:
(1)把点分成出度>入度和入度>出度两种
(2)跑一遍网络流
然后会发现由于n很大,会TLE,于是进行改进:
发现两条滑梯交叉滑一定没有不交叉滑来得好(就是简单地贪心思想)
于是对两类点排序,直接一个一个配对答案一定是最小的。
另一题:
六、贪心的更多例题
BZOJ1691 [Usaco2007 Dec]挑剔的美食家
七、More about贪心
贪心作为一类重要的信息学算法,一般并不是单独使用的
有时会利用堆来优化,也可能配合hash甚至平衡树进行问题的求解
当然也可以作为一个算法的一部分(如Dijkstra),或者”部分贪心思”
当然这种看似简单、其实内容丰富的算法就可以被出在NOIp中。。。。。。