如题,贪心算法隶属于提高算法效率的方法,也常与动态规划的思路相挂钩或一同出现。下面介绍几个经典贪心问题。(参考自刘汝佳著《算法竞赛入门经典》)。
P.S.下文皆是我一个字一个字敲出来的,绝对“童叟无欺”,哈哈。(。⌒∇⌒) 耗费了我的很多时间,所以——希望对大家有帮助啊~ (=^‸^=)

一、背包相关问题

1.最优装载问题:给出N个物体,有一定重量。请选择尽量多的物体,使总重量不超过C。
解法:只关心数量多,便把重量从小到大排序,依次选,直到装不下。

2.部分背包问题:给出N个物体,有一定重量和价值。请选择一些物体的一部分使在总重量不超过C的条件下总价值最大。
解法:关心总价值大,物体可取部分,便优先取单位重量价值较大的物体。

3.乘船问题:有N个人,有一定重量。每艘船的最大载重量均为C,且最多载2人。请用最少的船装载所有人。
解法:关心数量少,要尽量使每艘船的实际载重量尽量接近于最大载重量。便把重量从小到大排序,每艘船依次先载一个人,再载重量最接近船的剩余可载重量的人。这样可以使眼前的消费(剩余载重量)最少。
实现:用2个变量 l , r 分别从两头往中间移动,l 和 r 可共乘一艘船,或 r 自己乘一艘船。

二、区间相关问题

1.选择不相交区间:数轴上有N个开区间(Li,Ri),请选择尽量多个区间,并保证这些区间两两没有公共点。
解法:先把这些区间按找 Ri 从小到大的顺序排序,再对按序排列的每2个区间A,B分情况讨论:(1)A被B包含,选A最优;(2)A右边的一部分与B左边的一部分相交,选A最优,因为选A比B减少了与后面区间相交的可能性;(3)A、B不相交,便2个都选。总的来说就是排序后,从左到右选第一个没有与前面已选的区间相交的区间。O(n)。
拓展:那么如果可以一共覆盖两次,那该怎么选?         ——也就是【bzoj3433】{Usaco2014 Jan}Recording the Moolympics(算法效率--贪心)

2.区间选点问题:数轴上有N个闭区间[Li,Ri],请选择尽量少的点,使得每个区间内都至少有一个点。
解法:同样地先把这些区间按找 Ri 从小到大的顺序排序,再分类讨论:(1)A被B包含,不需理会B; P.S.没有明显的思路就暂时不推到具体选哪一个点 (≡・ x ・≡) (2)A右边的一部分与B左边的一部分相交,当拓展到3个或以上都有一部分重叠时,肯定选第一个区间的右端点,以使这个点处于更多的区间内;(3)A、B不相交,便各自随意填一个点。总的来说就是排序后,从左到右选第一个没有与前面已选的区间相交的区间的右端点。O(n)。

3.区间覆盖问题问题:数轴上有N个闭区间[Li,Ri],选择尽量少的区间覆盖一条指定线段[s,t]。
实现:先预处理一遍把线段外的区间的所有部分去掉,然后按 Li 从小到大的顺序排序,选当前 Ri 最大的。再选剩下的起点在刚选完的区间的右端点之前的右端点最右的区间。O(n)。

三、Huffman编码

最优编码问题:给出N个字符的频率 ci ,给每个字符赋予一个01编码串,使得任意一个字符的编码不是另一个字符编码的前缀,而且编码后总长度(每个字符的频率与编码长度乘积的总和)尽量小。

解法:
   Step 1.从01串,转换为构造一棵最优的编码树,左孩子是0,右孩子是1。而由于是编码,不能其中一个是另一个的前缀,便所有的字符都是叶子结点,不存在任一个是另一个的祖先,且要最优便不会叶子结点不是一个编码。。。
   Step 2.转换问题之后便用Huffman算法就可以了。∠※  把每个字符看作一个单结点子树放在一个树集合中,每棵子树的权值等于相应字符的频率。每次取权值最小的两棵子树合并成一棵新树,并重新放到集合中。新树的权值等于两棵子树权值之和。可以通过2个结论证明其正确性:1.贪心选择性质,使得第一步贪心法选择保留最优解。设x和y是频率最小的两个字符,则存在前缀码使得x和y具有相同码长,且仅有最后一位编码不同;2.最优子结构性质,使得原问题的最优解包含子问题的最优解。设 x 和 y 是有相同父亲结点 z 的两个叶子结点,那么把它们两个去掉,而留下 z 的最优编码树不会变。即——通过确定“”就知道这个算法是正确的啦。

实现:先按照频率把所有字符排序为一个队列P,再建一个队列Q存新的结点。先合并P最前面的2个结点后把新结点放在另一个队列Q,删除这2个结点。由于两个队列都是有序的,就可以接着从P最前面的2个结点后Q的前2个结点中选出2个频率最小的结点合并,新结点同样放在另一个队列,知道队列P为空。所以总时间复杂度是O(n log n+n)≈O(n log n)。我之前打过一道运用了这个知识点的题——【uva 10954】Add All(算法效率--Huffman编码+优先队列)

关于贪心算法的经典问题(算法效率 or 动态规划)的更多相关文章

  1. 【十大经典数据挖掘算法】AdaBoost

    [十大经典数据挖掘算法]系列 C4.5 K-Means SVM Apriori EM PageRank AdaBoost kNN Naïve Bayes CART 1. 集成学习 集成学习(ensem ...

  2. 基于python的七种经典排序算法

    参考书目:<大话数据结构> 一.排序的基本概念和分类 所谓排序,就是使一串记录,按照其中的某个或某些关键字的大小,递增或递减的排列起来的操作.排序算法,就是如何使得记录按照要求排列的方法. ...

  3. 【最全】经典排序算法(C语言)

    算法复杂度比较: 算法分类 一.直接插入排序 一个插入排序是另一种简单排序,它的思路是:每次从未排好的序列中选出第一个元素插入到已排好的序列中. 它的算法步骤可以大致归纳如下: 从未排好的序列中拿出首 ...

  4. C++经典排序算法总结

    转发请注明出处:https://www.cnblogs.com/fnlingnzb-learner/p/9374732.html 最近在研究一些经常用到的东西想把它们做一个汇总,想了想用到最多的应该是 ...

  5. c++经典排序算法全集(转)

    C++排序算法全集 排序算法是一种基本并且常用的算法.由于实际工作中处理的数量巨大,所以排序算法对算法本身的速度要求很高. 一.简单排序算法 由于程序比较简单,所以没有加什么注释.所有的程序都给出了完 ...

  6. 基于python的七种经典排序算法(转)

    一.排序的基本概念和分类 所谓排序,就是使一串记录,按照其中的某个或某些关键字的大小,递增或递减的排列起来的操作.排序算法,就是如何使得记录按照要求排列的方法. 排序的稳定性:经过某种排序后,如果两个 ...

  7. JavaScript 数据结构与算法之美 - 十大经典排序算法汇总(图文并茂)

    1. 前言 算法为王. 想学好前端,先练好内功,内功不行,就算招式练的再花哨,终究成不了高手:只有内功深厚者,前端之路才会走得更远. 笔者写的 JavaScript 数据结构与算法之美 系列用的语言是 ...

  8. 一文搞定十大经典排序算法(Java实现)

    本文总结十大经典排序算法及变形,并提供Java实现. 参考文章: 十大经典排序算法总结(Java语言实现) 快速排序算法—左右指针法,挖坑法,前后指针法,递归和非递归 快速排序及优化(三路划分等) 一 ...

  9. python 经典排序算法

    python 经典排序算法 排序算法可以分为内部排序和外部排序,内部排序是数据记录在内存中进行排序,而外部排序是因排序的数据很大,一次不能容纳全部的排序记录,在排序过程中需要访问外存.常见的内部排序算 ...

随机推荐

  1. 十七:SQL注入之二次加解密,DNS注入

    加解密,二次,DNSlog注入 注入原理,演示案例,实际应用. less-21关,base64进行解密 encode加密decode解密 cookie处注入 判断加密算法,然后进行注入 less-24 ...

  2. SQL中的主键,候选键,外键,主码,外码

    1.码=超键:能够唯一标识一条记录的属性或属性集. 标识性:一个数据表的所有记录都具有不同的超键 非空性:不能为空 有些时候也把码称作"键" 2.候选键=候选码:能够唯一标识一条记 ...

  3. redis持久化怎么选?成年人从来不做选择...

    前言 面试官:你知道 redis 是的怎么做持久化的吗? 我:我知道 redis 有两种方式,一种是 RDB,一种是 AOF. 面试官:那这两种方式具体是怎么做的,它们的区别是什么,生产环境中到底应该 ...

  4. MalformedByteSequenceException: 1字节的 UTF-8 序列的字节 1 无效

    记住,每次修改了配置之后都 clean 一下,把 target 删除 第一种解决方案 去掉 pom.xml 中的 properties <properties> <maven.com ...

  5. (十六)re模块

    正则表达式并不是Python的一部分,本质而言,正则表达式(或 RE)是一种小型的.高度专业化的编程语言.正则表达式是用于处理字符串的强大工具,很多编程语言都支持正则表达式的语法. 字符匹配分为普通字 ...

  6. 【SpringBoot】Spring Boot 集成SwaggerAPI

    Spring Boot 集成SwaggerAPI 文章目录 Spring Boot 集成SwaggerAPI Swagger 添加依赖 配置类 config 控制类 controller 接口测试 页 ...

  7. 【Linux】Centos7 安装redis最新稳定版及问题解决

    ------------------------------------------------------------------------------------------------- | ...

  8. 【Oracle】用sqlplus登录的各种方式

    1.本地登录 sqlplus / as sysdba 2.账号密码登录 sqlplus user/passwd 3.选择实例登录 sqlplus user/passwd@实例名   例如 sqlplu ...

  9. AWD生存之道

    比赛开始阶段 常见漏洞的防御手段:https://www.freebuf.com/articles/web/208778.html 一.登陆SSH 重点 如果ssh的密码不是随机密码,记得一开始就进行 ...

  10. kettle数据质量统计

    1.利用Kettle的"分组","JavaScript代码","字段选择"组件,实现数据质量统计.2.熟练掌握"JavaScrip ...