算法六——贪心

文章出处:极客时间《数据结构和算法之美》-作者:王争。该系列文章是本人的学习笔记。

1 背豆子的例子

假设我们有一个可以容纳 100kg 物品的背包,可以装各种物品。我们有以下 5 种豆子,每种豆子的总量和总价值都各不相同。为了让背包中所装物品的总价值最大,我们如何选择在背包中装哪些豆子?每种豆子又该装多少呢?

我们最直接的思路是算出每种豆子每kg的价值,按照价值从大到小排序。先装价值高的。单价从高到低排列,依次是:黑豆、绿豆、红豆、青豆、黄豆,所以,我们可以往背包里装 20kg 黑豆、30kg 绿豆、50kg 红豆。

2 贪心解决问题的步骤

1 当我们看到这类问题的时候想到要用贪心:针对一组数据,定义限制值和期望值,希望从中选择几个数据,在满足限制值的情况下,期望值最大。
例子中限制值是背包总容量,期望值是总价值最大。

2 我们尝试看下这个问题是否可以用贪心解决:每次选择当前情况下,在对限制值同等贡献量的情况下,对期望值贡献最大。
优先选择黑豆,在同样装1kg的时候,增加总价值最多。

3 我们举几个例子看下,用贪心得到的结果是不是最优的。大部分情况下,举几个例子就可以,贪心的证明是非常复杂的。

3 贪心实战例子

3.1 分糖果

有m个糖果,n个孩子。我们要把这个糖果分给孩子,一个孩子最多只能有一个糖果。糖果数量小于孩子数量。
每个糖果的大小也不同,这m个糖果的大小分别为s1、s2…sm。每个孩子对糖果的需求量不同,分别为t1、t2…tn。只有糖果大小大于等于孩子需求量的时候,孩子才能满足。
怎么分配才能让满足更多的孩子。

限制值是:糖果的数量。期望值是:获得满足的孩子的个数越多越好。
我们尝试用贪心解决。先满足需求量低的孩子。因为需求量低的孩子更容易满足,而且无论孩子需求量大小,满足一个,就可以让期望值加1。糖果按照从小到大排序,在满足当前孩子需求量的范围内选择最小的糖果。更大的糖果应该用来满足需求量更大的孩子。糖果无论大小,分配一个,就是给限制值加1。
所以,分配方案是:孩子按照需求量从小到大排序,糖果选择满足需求量的最小的糖果。可以满足更多的孩子。

3.2 钱币找零

当给别人找零的时候,我们希望找零的钱的数量越少越好。当然,钱的总量是要足够的。例如找25元,一张20+一张5元是最好的选择。

3.3 区间覆盖

假设我们有 n 个区间,区间的起始端点和结束端点分别是 [l1, r1],[l2, r2],[l3, r3],……,[ln, rn]。我们从这 n 个区间中选出一部分区间,这部分区间满足两两不相交(端点相交的情况不算相交),最多能选出多少个区间呢?

我们假设最左端是lmin,最右端是rmax。这就要求在[lmin,rmax]区间上找到数量更多的不重合的线段。我们按照左边端点从小到大排序这几个区间。每次选择的时候左边端点和前面已经覆盖的区间不重合,右边端点又尽可能的小。这样可以让剩下的未覆盖的区间更大,未来放置更多的区间段。

在这里插入图片描述

4 霍夫曼压缩编码

假设一篇文章有1000个字符,每个字符1个字节=8位。总共需要8000个bits。

如果这1000个字符只包含6种字符,分别为a、b、c、d、e、f。只需要3位就可以表示这6个字符。总共需要3000个bits。比最开始空间减少了。

a(000)、b(001)、c(010)、d(011)、e(100)、f(101)

是否可以再压缩呢?使用霍夫曼编码。
霍夫曼编码不仅考察文件中有多少种不同的字符,还统计不同字符的出现频率。根据频率不同,选择不同长度的编码。根据贪心思想,字符频率越高,使用的编码稍短;字符频率低,使用的编码稍长。当编码不等长的时候,怎么从压缩文件中读字符呢?这个时候我们要求一个字符不能是另外一个字符的前缀。

假设这 6 个字符出现的频率从高到低依次是 a、b、c、d、e、f。我们把它们编码下面这个样子,任何一个字符的编码都不是另一个的前缀,在解压缩的时候,我们每次会读取尽可能长的可解压的二进制串,所以在解压缩的时候也不会歧义。经过这种编码压缩之后,这 1000 个字符只需要 2100bits 就可以了。

4.1 设计霍夫曼树

4.1.1 插入队列,形成一棵树

如何设计字符编码呢?按照出现频率由低到高排序。我们把每个字符看作一个节点,并且付带着把频率放到优先级队列中。我们从队列中取出频率最小的两个节点 A、B,然后新建一个节点 C,把频率设置为两个节点的频率之和,并把这个新节点 C 作为节点 A、B 的父节点。最后再把 C 节点放入到优先级队列中。重复这个过程,直到队列中没有数据。

在这里插入图片描述

4.2 编码

现在,我们给每一条边加上画一个权值,指向左子节点的边我们统统标记为 0,指向右子节点的边,我们统统标记为 1,那从根节点到叶节点的路径就是叶节点对应字符的霍夫曼编码。
在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/424558.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

BZOJ 1827: [Usaco2010 Mar]gather 奶牛大集会 树形DP + 带权重心

Description Bessie正在计划一年一度的奶牛大集会&#xff0c;来自全国各地的奶牛将来参加这一次集会。当然&#xff0c;她会选择最方便的地点来举办这次集会。每个奶牛居住在 N(1<N<100,000) 个农场中的一个&#xff0c;这些农场由N-1条道路连接&#xff0c;并且从任意一…

[运动][组合]睡前运动

保持核心肌群力量 入门级组合运动 全身从上到下 俯卧撑 手部肩部 卷腹 腹部 仰卧抬腿 臀部 深蹲 下肢力量 扶墙踮脚 小腿

第五十二期:Java开发数据库设计的14个技巧,你知道几个?

可以是一对一、一对多、多对多的关系。在一般情况下&#xff0c;它们是一对一的关系&#xff1a;即一张原始单据对应且只对应一个实体。在特殊情况下&#xff0c;它们可能是一对多或多对一的关系&#xff0c;即一张原始单证对应多个实体&#xff0c;或多张原始单证对应一个实体…

算法八——动态规划

1 0-1背包问题 背包能够承受的总重量一定w&#xff0c;每个物品的总量不同int[] weight表示。怎么放才能让背包中物品的总重量最大。 每次决定一种物品&#xff0c;每一层能够达到的状态 state[][] 第0个物品的重量是2&#xff0c;要么装入背包&#xff0c;要么不装入背包&a…

《鸟哥的Linux私房菜--基础篇》学习

第四章 显示日期与时间的指令&#xff1a;date 输入&#xff1a; (base) liyihuadeMacBook-Pro:~ liyihua$ date 输出&#xff1a; Thu Jun 6 08:44:02 CST 2019显示日历指令&#xff1a;cal 输入&#xff1a; (base) liyihuadeMacBook-Pro:~ liyihua$ cal 输出&#xff1a; J…

第五十三期:公司如何选择数据库?DynamoDB、Hadoop和MongoDB 大比拼

随着公司数据存储方式的不断扩展&#xff0c;本文旨在比较公司使用的一些更现代的数据库系统——了解DynamoDB&#xff0c;Hadoop和MongoDB可以提供哪些功能将帮助用户针对业务模型做出更好的决策。 作者&#xff1a;久谦 用户如何选择最能满足当前业务需求的数据库&#xff…

[引用格式][中文论文][毕业论文]毕业论文引用格式 英文引用文献间隔过大

英文引用文献间隔过大&#xff0c;需要选中该条英文引用文献&#xff0c;在段落设置的中文版式设置西文换行&#xff0c;设置后再进行微调 设置前 设置后 设置方法

动态规划——0-1背包问题

文章出处&#xff1a;极客时间《数据结构和算法之美》-作者&#xff1a;王争。该系列文章是本人的学习笔记。 1 0-1背包问题 背包能够承受的总重量一定w&#xff0c;每个物品的总量不同int[] weight表示。怎么放才能让背包中物品的总重量最大。 每次决定一种物品&#xff0c…

003-JavaString数据类型

String类型可以和8中基本数据类型做运算(byte/short/char/int/long/float/double/boolean),且只能是连接运算 1. 区分 连接符 和 “” 的区别 char c a; int num 10; String str "hello"; System.out.println(c str num); //ahello10 System.out.println(str (…

第五十四期:MongoDB与MySQL:如何选择

MongoDB和MySQL分别是领先的开源NoSQL和关系数据库。哪个最适合您的应用程序? 作者&#xff1a;XEyes行走的CODE来源 MongoDB和MySQL分别是领先的开源NoSQL和关系数据库。哪个最适合您的应用程序? 在1990年代的互联网泡沫时期&#xff0c;用于Web应用程序的一种通用软件堆栈…

Centos7下实现多虚拟机互信

假设CentOS 7三台虚拟机A(192.168.111.10)、B(192.168.111.11)、C(192.168.111.12)&#xff0c;需要保证三台虚拟机之间网络的连通性。 操作步骤: 一、在A机上配置 ①以root用户登录&#xff0c;更改ssh配置文件 /etc/ssh/sshd_configRSAAuthentication yes #启用rsa认证Pubkey…

动态规划——矩阵中的最短路径长度

文章出处&#xff1a;极客时间《数据结构和算法之美》-作者&#xff1a;王争。该系列文章是本人的学习笔记。 题目 假设我们有一个 n 乘以 n 的矩阵 w[n][n]。矩阵存储的都是正整数。棋子起始位置在左上角&#xff0c;终止位置在右下角。我们将棋子从左上角移动到右下角。每次…

[密码学基础][每个信息安全博士生应该知道的52件事][Bristol Cryptography][第19篇]Shamir密钥交换场景

这是一系列博客文章中最新的一篇&#xff0c;该文章列举了“每个博士生在做密码学时应该知道的52件事”:一系列问题的汇编是为了让博士生们在第一年结束时知道些什么。 Shamir密钥交换场景是一个被Adi Shamir提出的算法.算法允许多方分割一个密码,例如一个密钥.当足够多的秘密结…

第五十五期:MongoDB数据库误删后的恢复

如果部署的是 MongoDB 复制集&#xff0c;这时还有一线希望&#xff0c;可以通过 oplog 来尽可能的恢复数据;MongoDB 复制集的每一条修改操作都会记录一条 oplog&#xff1b;如果对 MongoDB 做了全量备份 增量备份&#xff0c;那么可以通过备份集及来恢复数据。 作者&#xf…

037-PHP如何返回闭包函数实例

<?php /*: 如何返回闭包函数实例*/# 直接调用将不会输出$txt的内容function demo(){$txt 我爱PHP;$func function () use ($txt) {echo $txt;};# 这里不再直接调用&#xff0c;而且是把实例返回return $func; # 区别于直接写 $func;}# 测试一下 $res demo(); // 函数返…

动态规划——莱文斯坦距离

文章出处&#xff1a;极客时间《数据结构和算法之美》-作者&#xff1a;王争。该系列文章是本人的学习笔记。 莱文斯坦距离 在搜索引擎中会有搜索词纠错的功能。这个功能背后的原理是编辑距离。 编辑距离 编辑距离是量化两个词之间的相似度。 编辑距离是指将一个字符串变为…

[密码学基础][每个信息安全博士生应该知道的52件事][Bristol Cryptography][第18篇]画一个/描述ECB,CBC,CTR模式的操作

操作模式:块密码的安全性依赖于加解密一个固定长度的明文块.当加密或者解密消息的时候,块是被需要的.我们使用一种操作模式将明文的多个块链接在一起.我们会知道,这种链接在一起的方法是十分重要. 电子密码本(ECB)模式:加密,解密. ECB模式是最直接的方法.明文被分割成m块.每一…

动态规划——最长公共子序列长度

最长公共子序列长度是编辑距离的另外一种表示方法。只允许添加、删除字符两种惭怍。它表征的是两字符串之间的相似度。 解决思路是&#xff1a; 如果a[i]b[j]&#xff0c;则 公共子序列长度加1&#xff0c;继续考察a[i1]和b[j1]。 如果a[i]!b[j]&#xff0c;则删除a[i]或者在b[…

【转】store_schema.sql

来源&#xff1a;https://www.cnblogs.com/cenliang/p/5162939.html 这个是《精通Oracle Database 12c SQL & PL/SQL编程(第三版)》的数据&#xff0c;我用的是Oracle11g版本&#xff0c;做了些微调&#xff0c;如日期格式等。 给自己留个存档&#xff0c;以备不时之需~ --…

[密码学基础][每个信息安全博士生应该知道的52件事][Bristol Cryptography][第20篇]Merkle-Damgaard hash函数如何构造

这里讲的是MD变换,MD变换的全称为Merkle-Damgaard变换.我们平时接触的hash函数都是先构造出一个防碰撞的压缩函数.然后先证明这个小的,固定长度的压缩函数是安全的,然后再用它构造一个任意长度的哈希算法.虽然存在很多其它的构造方法,MD是迄今为止最常用的(至少是被用到最多的)…