【算法小讲堂】#1 贪心算法

引入——关于贪心算法

我们先来做一个小游戏——现在假设自己是一个小偷,桌上有一些物品,包括一台iPhone15、一个充电宝、一个眼罩和一个溜溜梅。此时,你听说警察即将到来,那么你会先带走哪个东西呢?

一般来讲,时间一定的话,我们通常会先拿走桌面上最贵的物品

“先拿最贵的走”,这种思想就是贪心

贪心算法解决的问题大致如此——

【从大集合中选出东西】

  • 排序
  • 按顺序选

如此,收益最大。


可是,为什么每次选“最贵的”,最终收益就是最大的?

这并不明显。

很多时候,贪心算法需要严格方式证明,在不同的情景下。


示例——排队接水问题

n n n个同学排队接水,接水的时间分别是 t 1 t1 t1 t 2 t2 t2 t 3 t3 t3 t 4 t4 t4 t 5 t5 t5,…, t n tn tn

  • 如何安排同学接水的顺序?
  • 使得平均接水时间最短。
  • 并计算出最短的平均接水时间。

分析——特例假想

假设这 n n n名同学打水的时间普遍较短,除了其中的同学小明,他拿了一个水塘大(夸张)的盆来打水。

此刻,如果让他站在队伍的最前面,其他同学等待时间是不是就非常非常久了,我们的平均等待时间想必就非常大了。

因此,合理的安排是——

让打水快的同学尽可能站在队伍前面。

模型——解决问题的一般方法

我们需要按一定的步骤解决此类问题,一般来讲,第一步是排序,明白什么样的同学应该排在前面;第二步是选择,模拟此过程计算出平均接水时间

A 排序

找到符合贪心思想的排序方案——打水快的排前面。

B 选择

依次序进行选择,模拟目标过程计算所需答案。

补充 数学证明

这种符合直觉的贪心方法未必能够经得起数学的推敲。为了保证做法的正确,我们通常还要建立数学模型,利用数学手段证明这一解决问题的方法是行之有效的。


贪心算法的问题中,常见地需要使用到诸如排序不等式的数学公式。请添加图片描述


一些尝试——加上一些限制条件

在一开始,我们假设了一个情境。

此时我们希望加入再一些限制条件,使得其更符合现实生活——

  • 背包的容量是有限的
  • 每一样物品是既有重量又有价值的

倘若这样,那么我们就不仅仅需要考虑物品的价值

因为向背包装入最贵的东西后,可能再也没用地方装下其余同样有很高价值但重量小的物品了。

请添加图片描述

此类问题成为了相对复杂一些的01背包问题。


现实生活中,还可能有以下情形——

由于警察并不一定往往在最后赶到,实际应该是在不同时刻赶到的概率是不相同的。

此时,我们需要利用动态规划解决,以求得最大的数学期望


再看冒泡排序——排序的贪心本质

请添加图片描述

先假定一个情形——你拿到一堆标着数字的卡片(可能有100张),你需要做的是给卡片按数字从小到大的顺序进行排序

你本能会做的是先铺开这些卡片,整体上看看这些数字大小。

当你的眼睛落在任意两张不同数字的卡片上,会有这样的情况——

(左边的卡片是 N 1 N1 N1,右边的卡片是 N 2 N2 N2

目标的情形是 N 1 < N 2 N1<N2 N1<N2,所以如果左边的数字大于右边的数字,我们尝试交换

显然,这种做法没有什么条理。但是可以确信的是——

在每一次操作后,我们都更加接近那个正确的答案。

而经过有限次操作后,就一定能够得到最优解,即正确的排序。

冒泡排序,其实就是按照一定的规律执行判断-交换的步骤。

思想的本质依旧是贪心


贪心的局部探索——动态规划

请添加图片描述

一个思考问题:给出一个山的三维模型(图片见上),目标求得此山中的最低点。

假设你是一位在这个山中迷路的攀登者,而山里起了大雾,你需要尽快到山的低洼处修整。你只能知道你所站的地方的坡度,没有其余办法找到那个低洼处

此时,为找到低洼处,我们会做的一定是一直向**“下”走,即一直下坡,直到不能再下坡**。

最终找到的未必是最低点,寻找的过程中很有可能一步就走到了再也回不去的道路(指远离最优解),但是我们知道,至少这样,让我们错误的概率更小一些。因为哪怕这个点不是全局中的最优解,它也会是我在这个区域能够找到的最好的解

这个试探的过程,我们称之为局部搜索


贪心算法的问题实例

🟢 [NOIP1998 提高组] 拼数

比较传统的贪心问题,解决问题的关键在于比较和交换相邻的数字串,一步步逼近最佳的答案。

题目描述

设有 n n n 个正整数 a 1 … a n a_1 \dots a_n a1an,将它们联接成一排,相邻数字首尾相接,组成一个最大的整数。

输入格式

第一行有一个整数,表示数字个数 n n n

第二行有 n n n 个整数,表示给出的 n n n 个整数 a i a_i ai

输出格式

一个正整数,表示最大的整数

样例 #1

样例输入 #1

3
13 312 343

样例输出 #1

34331213

样例 #2

样例输入 #2

4
7 13 4 246

样例输出 #2

7424613

提示

对于全部的测试点,保证 1 ≤ n ≤ 20 1 \leq n \leq 20 1n20 1 ≤ a i ≤ 1 0 9 1 \leq a_i \leq 10^9 1ai109

NOIP1998 提高组 第二题


🟢 [NOIP2012 提高组] 国王游戏

此题级别为普及+/提高

与前面一题不同的是,这里增加了变量,考虑时不妨先手动从简单的情形起开始模拟。

题目描述

恰逢 H 国国庆,国王邀请 n n n 位大臣来玩一个有奖游戏。首先,他让每个大臣在左、右手上面分别写下一个整数,国王自己也在左、右手上各写一个整数。然后,让这 n n n 位大臣排成一排,国王站在队伍的最前面。排好队后,所有的大臣都会获得国王奖赏的若干金币,每位大臣获得的金币数分别是:排在该大臣前面的所有人的左手上的数的乘积除以他自己右手上的数,然后向下取整得到的结果。

国王不希望某一个大臣获得特别多的奖赏,所以他想请你帮他重新安排一下队伍的顺序,使得获得奖赏最多的大臣,所获奖赏尽可能的少。注意,国王的位置始终在队伍的最前面。

输入格式

第一行包含一个整数 n n n,表示大臣的人数。

第二行包含两个整数 a a a b b b,之间用一个空格隔开,分别表示国王左手和右手上的整数。

接下来 n n n 行,每行包含两个整数 a a a b b b,之间用一个空格隔开,分别表示每个大臣左手和右手上的整数。

输出格式

一个整数,表示重新排列后的队伍中获奖赏最多的大臣所获得的金币数。

样例 #1

样例输入 #1

3 
1 1 
2 3 
7 4 
4 6

样例输出 #1

2

提示

【输入输出样例说明】

1 1 1 2 2 2 3 3 3 这样排列队伍,获得奖赏最多的大臣所获得金币数为 2 2 2

1 1 1 3 3 3 2 2 2 这样排列队伍,获得奖赏最多的大臣所获得金币数为 2 2 2

2 2 2 1 1 1 3 3 3 这样排列队伍,获得奖赏最多的大臣所获得金币数为 2 2 2

按$ 2$、 3 3 3、$1 $这样排列队伍,获得奖赏最多的大臣所获得金币数为 9 9 9

3 3 3 1 1 1、$2 $这样排列队伍,获得奖赏最多的大臣所获得金币数为 2 2 2

按$ 3$、 2 2 2 1 1 1 这样排列队伍,获得奖赏最多的大臣所获得金币数为 9 9 9

因此,奖赏最多的大臣最少获得 2 2 2 个金币,答案输出 2 2 2

【数据范围】

对于 20 % 20\% 20% 的数据,有 1 ≤ n ≤ 10 , 0 < a , b < 8 1≤ n≤ 10,0 < a,b < 8 1n10,0<a,b<8

对于 40 % 40\% 40% 的数据,有$ 1≤ n≤20,0 < a,b < 8$;

对于 60 % 60\% 60% 的数据,有 1 ≤ n ≤ 100 1≤ n≤100 1n100

对于 60 % 60\% 60% 的数据,保证答案不超过 1 0 9 10^9 109

对于 100 % 100\% 100% 的数据,有 1 ≤ n ≤ 1 , 000 , 0 < a , b < 10000 1 ≤ n ≤1,000,0 < a,b < 10000 1n1,000,0<a,b<10000

NOIP 2012 提高组 第一天 第二题

🟨参考与引用
洛谷
贪心算法基础 (JSOI24 冬令营) 南京大学-蒋炎岩

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

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

相关文章

matlab关键路径的工序安排和dijkstra路径规划

1、内容简介 略 59-可以交流、咨询、答疑 2、内容说明 略 3、仿真分析 略 matlab关键路径的工序安排和dijkstra路径规划_哔哩哔哩_bilibili 4、参考论文 略

2024 春招市场行情报告:鸿蒙人才遭“爆抢”

前言 2024年可以说是布道鸿蒙开发行业的最佳时机&#xff0c;华为在千帆启航仪式会中发布会中表示&#xff0c;已有200家头部企业加入原生开发当中&#xff0c;并且一直有高薪抢人的局面&#xff0c;这一信息已经引起业界很大关注。 因此有很多公司开始准备要招聘鸿蒙工程师&…

Redis+Caffeine 太强了!二级缓存可以这样实现!

在实际的项目中&#xff0c;我们通常会将一些热点数据存储到Redis或MemCache这类缓存中间件中&#xff0c;只有当缓存的访问没有命中时再查询数据库。 在一些场景下可能还需要进一步配合本地缓存使用&#xff0c;例如Guava cache或Caffeine&#xff0c;从而再次提升程序的响应…

nginx重新编译添加模块或去除不需要的模块

在使用nginx中&#xff0c;我们可能需要对已经安装的nginx进行添加或者删除模块 1、先查看nginx安装了哪一些模块 nginx -V2、来到nginx源码目录&#xff0c;根据如下规则&#xff0c;自行根据需求更改命令 如果要去掉nginx自带的模块&#xff0c;就是用–without做为前缀进…

DP读书:《工程热力学(第二版)》(一)绪论——能量及其利用

DP读书&#xff1a;《工程热力学&#xff08;第二版&#xff09;》绪论 0.1 能量及其利用 热力学——研究对象&#xff1a;能量 能量 物质能量传递 普遍规律 能源&#xff1a;直接提供能量的物质资源 一次能源&#xff1a;热能占比85% 直接利用——>冶金、采暖、炊煮 …

一文彻底搞懂并发与并行

文章目录 1. 并发&#xff08;Concurrency&#xff09;2. 并行&#xff08;Parallelism&#xff09;3. 总结 在Windows操作系统中&#xff0c;我们可以同时进行多项任务&#xff0c;比如观看电影、聊QQ&#xff0c;或者同时听歌和打游戏。尽管这些任务我们感觉在同一时间内似乎…

备战蓝桥杯————递归反转单链表的一部分

递归反转单链表已经明白了&#xff0c;递归反转单链表的一部分你知道怎么做吗&#xff1f; 一、反转链表Ⅱ 题目描述 给你单链表的头指针 head 和两个整数 left 和 right &#xff0c;其中 left < right 。请你反转从位置 left 到位置 right 的链表节点&#xff0c;返回 反…

JSON:简介与基本使用

目录 什么是JSON&#xff1f; JSON的基本结构 JSON的基本使用 在JavaScript中使用JSON 创建JSON对象 解析JSON字符串 生成JSON字符串 在其他编程语言中使用JSON 总结 什么是JSON&#xff1f; JSON&#xff0c;全称为JavaScript Object Notation&#xff0c;是一种轻量…

matlab经验模式分解的R波检测算法

1、内容简介 略 56-可以交流、咨询、答疑 2、内容说明 略 心血管疾病是威胁人类生命的主要疾病之一&#xff0c;而心电信号&#xff08;electrocardiogram, ECG&#xff09; 则是评价心脏功能的主要依据&#xff0c;因此&#xff0c;关于心电信号检测处理的研究一直为各方所…

这个元宵节,被云开发者安排了

元宵节快乐&#xff0c;同学们&#xff01;今天吃的汤圆都是什么馅儿的&#xff1f; 都说过了元宵&#xff0c;这个年才算是正式过完&#xff0c;2024年就算是正式开启。学堂君这里也准备了一份专属于开发者的小礼物&#xff0c;作为一点心意。 欢迎私信&#xff0c;发送暗号…

matlab 三质量-弹簧系统受激振力

1、内容简介 略 44-可以交流、咨询、答疑 建立系统运动方程&#xff0c;研究固有频率和对应主振型 2、内容说明 略 三质量&#xff0d;弹簧系统受激振力&#xff0c;并不考虑各自的阻尼。建立系统运动方程。 解&#xff1a;由于阻尼对固有频率没有影响&#xff0c;故本文不…

ClickHouse 指南(三)最佳实践 -- 主键稀疏索引

在ClickHouse主索引的实用介绍 ClickHouse release 24.1, 2024-01-30 1、简介 在本指南中&#xff0c;我们将深入研究ClickHouse索引。我们将详细说明和讨论: ClickHouse中的索引与传统的关系数据库管理系统有何不同ClickHouse是如何构建和使用表的稀疏主索引的什么是在Clic…