8.4 贪心法

1.背包问题:

①最优装载问题:把物体重量从小到大排列,依次选择每个物体,只顾眼前,却能得到最优解。

②部分背包问题:把物体的“价值除以重量的值”从小到大排序,一次选择每个物体(贪心只能对一个变量贪心,这是一种巧妙的转换)。

③乘船问题:只让眼前的浪费最少。(注意是让什么最少,是让浪费最少!)

2.区间相关问题(排序:排左边还是右边?):

①选择不相交区间:

②区间选点问题:

③区间覆盖问题:

3.定义:

在对问题求解时,总是做出在当前看来是最好的选择。也就是说,不从整体最优上加以考虑,他所做出的仅是在某种意义上的局部最优解。

其核心是根据题意选取一种量度标准。然后将这多个输入排成这种量度标准所要求的顺序,按这种顺序一次输入一个量。如果这个输入和当前已构成在这种量度意义下的部分最佳解加在一起不能产生一个可行解,则不把此输入加到这部分解中。一般和排序结合使用,排序排的关键变量的选取是重中之重。

对于一个给定的问题,往往可能有好几种量度标准。初看起来,这些量度标准似乎都是可取的,但实际上,用其中的大多数量度标准作贪婪处理所得到该量度意义下的最优解并不是问题的最优解,而是次优解。因此,选择能产生问题最优解的最优量度标准是使用贪婪算法的核心。

4.问题特点:

贪心策略适用的前提是:局部最优策略能导致产生全局最优解。

⑴随着算法的进行,将积累起其它两个集合:一个包含已经被考虑过并被选出的候选对象,另一个包含已经被考虑过但被丢弃的候选对象。

⑵有一个函数来检查一个候选对象的集合是否提供了问题的解答。该函数不考虑此时的解决方法是否最优。

⑶还有一个函数检查是否一个候选对象的集合是可行的,也即是否可能往该集合上添加更多的候选对象以获得一个解。和上一个函数一样,此时不考虑解决方法的最优性。

⑷选择函数可以指出哪一个剩余的候选对象最有希望构成问题的解。

⑸最后,目标函数给出解的值。

⑹为了解决问题,需要寻找一个构成解的候选对象集合,它可以优化目标函数,贪婪算法一步一步的进行。起初,算法选出的候选对象的集合为空。接下来的每一步中,根据选择函数,算法从剩余候选对象中选出最有希望构成解的对象。如果集合中加上该对象后不可行,那么该对象就被丢弃并不再考虑;否则就加到集合里。每一次都扩充集合,并检查该集合是否构成解。如果贪婪算法正确工作,那么找到的第一个解通常是最优的。

5.重要性质:

①贪心选择性质:

所谓贪心选择性质是指所求问题的整体最优解可以通过一系列局部最优的选择,换句话说,当考虑做何种选择的时候,我们只考虑对当前问题最佳的选择而不考虑子问题的结果。这是贪心算法可行的第一个基本要素。对于一个具体问题,要确定它是否具有贪心选择性质,必须证明每一步所作的贪心选择最终导致问题的整体最优解。

②最优子结构性质:

当一个问题的最优解包含其子问题的最优解时,称此问题具有最优子结构性质。问题的最优子结构性质是该问题可用贪心算法求解的关键特征。

6.哈弗曼编码:

①该方法完全依据字符出现概率来构造异字头的平均长度最短的码字,有时称之为最佳编码,一般就叫做Huffman编码。

②把每个字符看做一个单节点子树放在一个树集合中,每棵子树的权值等于相应字符的频率。每次取权值最小的两颗子树合并成一颗新树,并重新放到集合中。新树的权值等于两棵子树权值之和。

8.4 贪心法

时间: 2024-10-06 12:46:17

8.4 贪心法的相关文章

贪心法 codevs 1052 地鼠游戏

1052 地鼠游戏 时间限制: 1 s 空间限制: 128000 KB 题目等级 : 钻石 Diamond 题解 题目描述 Description 王钢是一名学习成绩优异的学生,在平时的学习中,他总能利用一切时间认真高效地学习,他不但学习刻苦,而且善于经常总结.完善自己的学习方法,所以他总能在每次考试中得到优异的分数,这一切很大程度上是由于他是一个追求效率的人. 但王钢也是一个喜欢玩的人,平时在学校学习他努力克制自己玩,可在星期天他却会抽一定的时间让自己玩一下,他的爸爸妈妈也比较信任他的学习能力

[LeetCode]wildcard matching通配符实现之贪心法

前天用递归LTE,昨天用动态规划LTE,今天接着搞,改用贪心法.题目再放一次: '?'匹配任意字符,'*'匹配任意长度字符串 Some examples: isMatch("aa","a") → false isMatch("aa","aa") → true isMatch("aaa","aa") → false isMatch("aa", "*"

贪心法

贪心法(Greedy Approach)又称贪婪法, 在对问题求解时,总是做出在当前看来是最好的选择,或者说是:总是作出在当前看来最好的选择.也就是说贪心算法并不从整体最优考虑,它所作出的选择只是在某种意义上的局部最优选择.当然,希望贪心算法得到的最终结果也是整体最优的.虽然贪心算法不能对所有问题都得到整体最优解,但对许多问题它能产生整体最优解.如单源最短路经问题,最小生成树问题等.在一些情况下,即使贪心算法不能得到整体最优解,其最终结果却是最优解的很好近似. 贪心法的设计思想 当一个问题具有以

C语言(贪心法)

C语言有这样一个规则,每一个符号应该包含尽可能多的字符.也就是说,编译器将程序分解成符号的方法是,从左到右一个一个字符地读入,如果字条可能组成一个符号,那么再读入下一个字符,判断已经读入的两个字符组成的字符串是否可能是一个符号的组成部分,如果可能,继续读入下一个字条,重复上述判断,直到读入的字符组成的字符串已经不再可能组成一个有意义的符号.这个处理的策略被称为"贪心法".需要注意的是,除了字符串与字符常量,符号的中间不能嵌有空白(空格.制表符.换行符等). 看一下下面的代码:想一下输出

算法题解之贪心法

Wiggle Subsequence 最长扭动子序列 思路1:动态规划.状态dp[i]表示以nums[i]为末尾的最长wiggle子序列的长度.时间是O(n^2). 1 public class Solution { 2 public int wiggleMaxLength(int[] nums) { 3 if (nums == null || nums.length == 0) { 4 return 0; 5 } 6 int[] pos_dp = new int[nums.length]; 7

贪心法-c语言的规则

在面试的过程中,有很多的考验对c的认识的情况,有时会被问到有关字符搭配以及运算先后顺序的问题,比如a+++++b的值,++i+++i+++i+i的值等类似的,这都属于c的符号方面的问题,那么怎样才能轻而易举的去认识它呢? c语言有这样的一个规则:那就是传说中的贪心法,规则是这样定的:每个符号应该包含尽可能多的字符,也就是说,我们的编译器将程序分解成符号的方法是,从左到右一个一个字符的读入,如果该字符可能组成一个符号,那么再读入下一个字符,然后在判断已经读入的两个字符是否有可能是一个符号或者一个符

ACM:贪心法:乘船问题。

题目:有n个人,第i个人的重量为wi,每艘船的最大载重量均为C,且最多只能乘两个人.用最少的船装载所有人. 分析:贪心法! 考虑最轻的人i,他应该和谁一起坐呢?如果每个人都无法和他一起坐船,那么唯一的方案就是每个人坐一艘船! 否则,他应该选择能和他一起坐船的人中最重的一个j. 这样的方法是贪心的!因为:它只是让"眼前"的浪费最少. 程序实现:我们只需用两个下标i和j分别表示当前考虑的最轻的人和最重的人,每次先将j往左移动,直到i和j可以共坐一艘船,然后i加1,j减1.并且重复上述操作!

理解动态规划、分治法和贪心法

本文转自:http://www.cnblogs.com/airwindow/p/4067902.html http://hi.baidu.com/35661327/blog/item/d5463e17f1e8d011972b439c.html 动态规划.分治法和贪心法都是利用求解子问题,而后利用子问题求解更上层问题,最终获得全局解决方案的方法. 但是三者的应用场景和性质却存在着极大的不同: 1.分治法 很容易与动态规划问题混淆,但两者却有着本质上的差异. 分治法采用的是递归的思想来求解问题,两个

杭电2037贪心法

#include<stdio.h> int main() { int n; int a[110],b[110],temp,temp1,count,time; int i,j; while(scanf("%d",&n)!=EOF&&n!=0) { count=0; time=0; for(i=0;i<n;i++) { scanf("%d%d",&a[i],&b[i]); } for(i=0;i<n-1;i