如题,贪心算法隶属于提高算法效率的方法,也常与动态规划的思路相挂钩或一同出现。下面介绍几个经典贪心问题。(参考自刘汝佳著《算法竞赛入门经典》)。
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. 图片质量评估论文 | 无监督SER-FIQ | CVPR2020

    文章转自:同作者微信公主号[机器学习炼丹术].欢迎交流,共同进步. 论文名称:SER-FIQ: Unsupervised Estimation of Face Image Quality Based ...

  2. 容器编排系统K8s之Prometheus监控系统+Grafana部署

    前文我们聊到了k8s的apiservice资源结合自定义apiserver扩展原生apiserver功能的相关话题,回顾请参考:https://www.cnblogs.com/qiuhom-1874/ ...

  3. 修改hosts文件后不生效,该怎么办

    对于web开发来说,经常需要修改hosts文件,用来将域名与ip对应匹配.但是有时候发现hosts文件明明已经改了,但就是不生效,页面还会跳到某个丧心病狂的私人小站.hosts文件不生效有很多种原因, ...

  4. tomcat控制台运行窗口中文乱码

    启动tomcat时出来的运行窗口中文乱码, 如图所示:看得有点不舒服 解决方法:找到Tomcat安装路径下的 /conf/logging.properties 文件 文件末尾添加语句: java.ut ...

  5. kubernets之服务的实现方式

    一  服务如何通过kubernetes集群的组件来实现其功能 1.1  节点上的所有的服务相关的功能实现都是通过节点上面的kube-proxy来实现的,服务提供了一个或者多个服务IP以及端口对客户端开 ...

  6. 处理Promise.reject()

    一般处理Promise.reject()都是catch住错误,然后进行错误处理,一般都是再次发起请求或者直接打印. 直接打印的情况用console.error()就可以了,而再次发起请求呢? 最好是先 ...

  7. ASP.NET Core错误处理中间件[4]: 响应状态码页面

    StatusCodePagesMiddleware中间件与ExceptionHandlerMiddleware中间件类似,它们都是在后续请求处理过程中"出错"的情况下利用一个错误处 ...

  8. RocketMQ—消息队列入门

    消息队列功能介绍 字面上说的消息队列是数据结构中"先进先出"的一种数据结构,但是如果要求消除单点故障,保证消息传输可靠性,应对大流量的冲击,对消息队列的要求就很高了.现在互联网的& ...

  9. EFCore 5 新特性 —— Savepoints

    EFCore 5 中的 Savepoints Intro EFCore 5中引入了一个新特性,叫做 Savepoints,主要是事务中使用,个人感觉有点类似于 Windows 上的系统还原点,如果事务 ...

  10. cfsetispeed、cfsetospeed和cfsetspeed探究

    在我https://www.cnblogs.com/Suzkfly/p/11055532.html这篇博客中有一个疑问,就是在串口设置波特率的域中,没有将输入输出波特率分开,那为什么会有几个不同的设置 ...