如题,贪心算法隶属于提高算法效率的方法,也常与动态规划的思路相挂钩或一同出现。下面介绍几个经典贪心问题。(参考自刘汝佳著《算法竞赛入门经典》)。
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. 【Java】标识符

    一.标识符 文章目录 一.标识符 1.标识符的命名规则 2.关键字.保留字.特殊值 3.code Java 对各种变量.方法和类等要素命名时使用的字符序列称为标识符.简单的说,凡是程序员自己命名的部分 ...

  2. Restful API是什么、为什么、怎么使用

    Restful API 文章目录 Restful API 1.REST是什么以及它的 6 个限制 REST是什么? REST的6个限制 2. Restful是什么 Restful是什么 RESTful ...

  3. iconv函数报错 Detected an illegal character in input string

    近日使用php代码导出文件为excel,一直乱码.导出修改编码都无效,最后发现,是需要修改php导出代码本身的编码.首先用记事本打开php代码,另存为,选择ANSI格式.然后打开iconv函数这个ph ...

  4. LeetCode783. 二叉搜索树节点最小距离

    题目 和LeetCode530没什么区别 1 class Solution { 2 public: 3 vector<int>ans; 4 int minDiffInBST(TreeNod ...

  5. Python输出有颜色的文字

    原创链接: https://www.cnblogs.com/easypython/p/9084426.html   我们在使用python运维与开发的过程中,经常需要打印显示各种信息.海量的信息堆砌在 ...

  6. SAP中数据库表长度的界定

    SAP中,如何查看表和关键字的长度?通过SE11菜单栏Extras->table width 可以看到.然而SAP在系统也会将表分类,特别是在可扩展的表维护视图中,分为如下几类      ult ...

  7. 二本学生拿到腾讯大厂offer的成长记录

    本人迈莫,是在20年以春招实习生的身份进入鹅厂,经过重重波折,最终成为鹅仔一份子.接下来我会以我亲生经历为例,分享一下普通大学的学生也是可以进去大厂,拭目以待!!! 初入大学 惨遭毒打 时间倒回到17 ...

  8. winform 窗体中顶部标题居中显示

    在网上看了很多例子,都不能居中,都有或多或少的问题 自己根据网友的代码改编入下: 先确随便写一个标题的内容: string titleMsg ="Winfrom Title" 获取 ...

  9. 通过封装openpyxl模块实现自己的Excel操作类

    """ excel类封装需要提供以下功能: 1.选择表单功能 2.读取一个单元格的数据功能 3.读取一行数据功能 4.读取表单中所有数据功能 5.往单元格中写入数据功能 ...

  10. 树莓派zero 使用usb串口连接

    使用minicom连接bash$ lsusbBus 002 Device 001: ID 1d6b:0003 Linux Foundation 3.0 root hubBus 001 Device 0 ...