C++知识点总结(19):高级贪心算法

高级贪心算法

  • 一、P1803 活动安排
    • 1. 审题
    • 2. 思路
      • 2.1 最优区间挑选方法
      • 2.2 分配时间方法
      • 2.3 排序方法
    • 3. 参考答案
  • 二、P1094 纪念品分组
    • 1. 审题
    • 2. 思路
      • 2.1 每组多少个方法
      • 2.2 搭配的方法
    • 3. 参考答案
  • 三、村民打水
    • 1. 审题
    • 2. 思路
    • 3. 参考答案
  • 四、习题
    • 1. 服务等待
      • 1.1 审题
      • 1.2 参考答案
    • 2. 春节糖果
      • 2.1 审题
      • 2.2 思路
      • 2.3 参考答案
    • 3. LC452 气球射击
      • 3.1 审题
      • 3.2 思路
      • 3.3 参考答案
  • 彩蛋

一、P1803 活动安排

1. 审题

题目描述

春节快要到了,耶斯莫拉大酒店在最近几天要举办 n n n 个活动,这些活动都需要使用酒店的大礼堂,而在同一时间,礼堂只能被一个活动使用。由于有些活动时间上有冲突,酒店管理人员只好让一些活动放弃使用礼堂而使用其他小的餐厅。现在给出n个活动使用礼堂的起始时间 b e g i n i begin_i begini 和结束时间 e n d i end_i endi ( b e g i n i < e n d i ≤ 32767 begin_i < end_i \le 32767 begini<endi32767),请你帮助酒店管理人员安排一些活动来使用礼堂,要求安排的活动尽量多。假设没有重新布置礼堂时间的消耗,即某个时间点完成活动的瞬间,就可以开始下一个活动。

输入描述

第一行一个整数 n n n( n ≤ 1000 n \le 1000 n1000);接下来的 n n n 行,每行两个整数,第一个 b e g i n i begin_i begini ,第二个是 e n d i end_i endi ( b e g i n i < e n d i ≤ 32767 begin_i < end_i \le 32767 begini<endi32767)。

输出描述

输出最多能安排的活动个数。

样例1

输入

11
3 5
1 4
12 14
8 12
0 6
8 11
6 10
5 7
3 8
5 9
2 13

输出

4

提示

2. 思路

2.1 最优区间挑选方法

  • 开始时间

不应该这么直接,因为开始时间的早晚会导致活动少,不是最优解。

  • 所用时间

如果在两个活动执行区间内有一个更短时间的活动,则错过了几个活动,不是最优解。

  • 结束时间

结束时间越早,说明后面剩余的连续时间越多
,是最优解。

2.2 分配时间方法

首先,一定要从一个区间开始遍历,因为如果这个区间包含了下个区间,那么选择这个区间不如选择下一个区间划算,选下个区间还能节省几个点来用于其他区间的选择。

2.3 排序方法

通过结束时间,从小到大进行排序(需要用到结构体 struct )。

3. 参考答案

#include <iostream>
#include <algorithm>
using namespace std;int n, rem, ans = 1;struct Node
{int l, r;
}a[1005];bool cmp(Node a, Node b)
{return a.r < b.r;
}int main()
{cin >> n;for (int i = 1; i <= n; i++){cin >> a[i].l >> a[i].r;}sort(a+1, a+n+1, cmp);int rem = a[1].r;for (int i = 2; i <= n; i++){if (a[i].l >= rem){ans++;rem = a[i].r;}}cout << ans;return 0;
}

二、P1094 纪念品分组

1. 审题

题目描述

元旦快到了,校学生会让乐乐负责新年晚会的纪念品发放工作。为使得参加晚会的同学所获得 的纪念品价值相对均衡,他要把购来的纪念品根据价格进行分组,但每组最多只能包括两件纪念品, 并且每组纪念品的价格之和不能超过一个给定的整数。为了保证在尽量短的时间内发完所有纪念品,乐乐希望分组的数目最少。
你的任务是写一个程序,找出所有分组方案中分组数最少的一种,输出最少的分组数目。

输入格式

输入文件 gift.in
n + 2 n+2 n+2 行:
第一行包括一个整数 w w w,为每组纪念品价格之和的上限。
第二行为一个整数 n n n,表示购来的纪念品的总件数 G G G
3 n + 23 n + 2 3 ~ n + 23 ~ n + 2 3 n+23 n+2 行每行包含一个正整数 P i P_i Pi 表示所对应纪念品的价格。

输出格式

输出文件 gift.out
一个整数,即最少的分组数目。

样例1

输入

100
9
90
20
20
30
50
60
70
80
90

输出

6

提示

50 % 50\% 50% 的数据满足: 1 ≤ n ≤ 15 1\le n\le15 1n15
100 % 100\% 100% 的数据满足: 1 ≤ n ≤ 3 × 1 0 4 1\le n\le3\times10^4 1n3×104 80 ≤ w ≤ 200 80\le w\le200 80w200

2. 思路

2.1 每组多少个方法

当和 ≤ w \le w w 的时候,优先 2 2 2 个一组。

2.2 搭配的方法

优先让危险的数字(越贵)找不危险的数字(越便宜),也就是大找小。
如果超过 w w w 则优先让大的组成 1 1 1 组。

3. 参考答案

#include <iostream>
#include <cstdio>
#include <algorithm>
using namespace std;int w, n, cnt;
int num[30005];int main()
{freopen("gift.in", "r", stdin);freopen("gift.out", "w", stdout);cin >> w >> n;for (int i = 1; i <= n; i++){cin >> num[i];}sort(num+1, num+n+1);int i = 1, j = n;while (i <= j){// 贵的配便宜的 if (num[j] + num[i] <= w){cnt++;j--;i++;}// 贵的单独一组 else{cnt++;j--;}}cout << cnt;fclose(stdin);fclose(stdout);return 0;
}

三、村民打水

1. 审题

题目描述

在一个小村子里,生活着 n n n 户人家。由于村里只有一口井,所以他们每天早上一户人家派一个人在这一口井前排队打水。由于每家的水桶大小不同,所以每个人的打水时间也不同。假如每个人打水的时间为 T i T_i Ti,请你编程找出这 n n n 个人排队的一种顺序,使得 n n n 个人的平均等待时间最小。

输入描述

共两行,第一行为 n n n;第二行分别表示第 1 1 1 个人到第 n n n 个人每人的打水时间 T i T_i Ti,每个数据之间有 1 1 1 个空格。

输出描述

共两行,第一行为一种排队顺序,即1到n的一种排列;第二行为这种排列方案下的平均等待时间(输出结果精确到小数点后两位)。

样例1

输入

10					
56 12 1 99 1000 234 33 55 99 812	

输出

3 2 7 8 1 4 9 6 10 5
291.90

提示

1 ≤ n ≤ 1 0 5 1 \le n \le 10^5 1n105
1 ≤ T i ≤ 1 0 6 1 \le T_i \le 10^6 1Ti106,不保证 T i T_i Ti 不重复
T i T_i Ti 重复时,按照输入顺序即可(sort 是可以的)

2. 思路

计算每个人的等待时间,并且累加得到总的等待时间 a n s ans ans。对于第 i i i 个人,他的等待时间为 ( n − i ) ∗ t i (n-i) * t_i (ni)ti,其中 n n n 是总人数, t i t_i ti 是第 i i i 个人的打水时间。

3. 参考答案

#include <iostream>
#include <iomanip>
#include <algorithm>
using namespace std;int n;
double ans;struct Node
{int idx;int t;
}person[100005];bool cmp(Node a, Node b)
{if (a.t != b.t){return a.t < b.t;}return a.idx < b.idx;
}int main() 
{cin >> n;for (int i = 1; i <= n; i++){person[i].idx = i;cin >> person[i].t;}sort(person+1, person+n+1, cmp);for (int i = 1; i <= n; i++){ans += person[i].t * (n-i);cout << person[i].idx << " ";}ans /= n;cout << endl << fixed << setprecision(2) << ans;return 0;
}

四、习题

1. 服务等待

1.1 审题

题目描述

小明新店开业,免费为顾客进行按摩服务,现在已经排了一个有 n n n 个人的队伍,其中第 i i i 个人需要 t[i] 分钟来服务,期间后面的人就要等着。如果一个人等待的时间大于了他被服务的时间,他就会失望,就会离开队伍。
你的任务是重排队伍,使失望的人尽量的少,并输出最多有多少个不失望的人。

输入描述

1 1 1 行一个整数 n n n,表示队伍人数。
接下来 n n n 行,每行一个整数,表示第i个人的服务时间 t [ i ] t[i] t[i]

输出描述

输出一行,为一个整数,表示最多不失望的人数。

样例1

输入

5
15 
2 
1 
5 
3

输出

4

提示

1 ≤ n ≤ 1 0 5 , 1 ≤ t [ i ] ≤ 1 0 3 1 \le n \le 10^5,1 \le t[i] \le 10^3 1n1051t[i]103

1.2 参考答案

#include <iostream>
#include <algorithm>
using namespace std;int n, cnt, wait;
int t[100005];int main()
{cin >> n;for (int i = 1; i <= n; i++){cin >> t[i];}sort(t+1, t+n+1);for (int i = 1; i <= n; i++){if (wait <= t[i]){cnt++;wait += t[i];}}cout << cnt;return 0;
}

2. 春节糖果

2.1 审题

题目描述

春节快到了,王老师给同学们准备了春节糖果,让胡图图负责糖果的发放工作。王老师准备的不同糖果美味度不同,为使得各位同学所获得的糖果美味度相对均衡,图图需要把购来的糖果根据美味度进行分组,但每组最多只能包括两份糖果,并且每组糖果的美味度之和不能超过一个给定的整数。为了保证在尽量短的时间内发完所有糖果,图图希望分组的数目最少。 由于胡图图比较糊涂,所以请你帮图图写一个程序,找出所有分组方案中分组数最少的一种,输出最少的分组数目。

输入描述

输入文件名 gift.in
n + 2 n+2 n+2 行:
1 1 1 行包括一个整数 w w w,为每组糖果美味度之和的上限。
2 2 2 行为一个整数 n n n,表示购来的糖果的总件数。
3 n + 2 3~n+2 3 n+2 行每行包含一个正整数 p i p_i pi ( 5 ≤ p i ≤ w 5 \le p_i \le w 5piw),表示所对应糖果的美味度。

输出描述

输出文件名 gift.out
仅一行,包含一个整数,即最少的分组数目。

样例1

输入

100
9
90
20
20
30
50
60
70
80
90

输出

6

提示

50 % 50\% 50%的数据满足: 1 ≤ n ≤ 15 1 \le n \le 15 1n15
100 % 100\% 100%的数据满足: 1 ≤ n ≤ 3 × 1 0 4 , 80 ≤ w ≤ 200 1 \le n \le 3 \times 10^4, 80 \le w \le 200 1n3×104,80w200

2.2 思路

  1. 将购来的糖果按照美味度从小到大进行排序。
  2. 使用双指针(尺取)来选择糖果,组成分组。
  3. 设置两个指针 l l l r r r,分别指向糖果数组的第一个和最后一个元素。
  4. 每次迭代中,判断左指针和右指针所指的糖果美味度之和是否小于等于给定的美味度上限 w w w
  • 如果是,表示可以将这两个糖果放在同一组内,我们将左指针向右移动一位,右指针向左移动一位。
  • 如果不是,表示这两个糖果无法放在同一组内,我们只能将右指针向左移动一位继续成组。
  1. 在每次迭代中,无论是否能放入同一组内,我们都将分组数目 c n t cnt cnt 自增。
  2. 当左指针超过右指针时,表示所有的糖果都已经处理完毕,此时 c n t cnt cnt 的值为最少的分组数目。

这种算法通过贪心的策略,每次选择美味度最小和最大的糖果进行配对,以保证尽可能多的糖果被分组。同时,通过排序操作,使得每次选择到的糖果的美味度是当前剩余糖果中最小的,这样有利于后续的分组过程。

2.3 参考答案

#include <iostream>
#include <cstdio>
#include <algorithm>
using namespace std;int w, n, cnt, sum;
int candies[30005];int main()
{freopen("gift.in", "r", stdin);freopen("gift.out", "w", stdout);cin >> w >> n;for (int i = 1; i <= n; i++){cin >> candies[i];}sort(candies+1, candies+n+1);int l = 1, r = n;while (l <= r){if (candies[l] + candies[r] <= w){l++;r--;}else{r--;}cnt++;}cout << cnt;fclose(stdin);fclose(stdout);return 0;
}

3. LC452 气球射击

3.1 审题

题目描述

游乐园举办了一场射气球的比赛,如果谁能使用最少的弓箭数量引爆所有气球,则会得到"最佳射手奖"。
规则如下:
在二维空间中有 n n n 个直径不同的球形气球,对于每个气球,提供的是水平方向上气球直径的开始和结束坐标。由于气球是被水平牵引的,所以Y坐标并不重要,因此只要知道气球直径的开始和结束的X坐标就足够了。每个气球的直径的开始坐标一定小于结束坐标。
一支弓箭可以沿着 X X X 轴从不同点完全垂直地射出。在坐标 X X X 处射出一支箭,若有一个气球的直径的开始和结束坐标为 ( a , b ) (a,b) (a,b),只要满足 a ≤ X ≤ b a ≤ X ≤ b aXb,则该气球会被引爆。
可以射出的弓箭的数量没有限制。弓箭一旦被射出之后,可以无限地前进。
如果要将所有气球全部被引爆,最少需要多少支弓箭呢?

输入描述

第一行有一个正整数 n n n( 1 ≤ n ≤ 1000 1\le n\le1000 1n1000)
接下来有 n n n 行,每一行有 2 2 2 个正整数 a a a b b b,分别表示气球直径的开始坐标和结束坐标( 1 ≤ a , b ≤ 32767 1\le a,b\le 32767 1a,b32767)。

输出描述

单独一行,表示引爆所有气球所需弓箭的最小数量。

样例1

输入

4
10 16
2 8
1 6
7 12

输出

2

3.2 思路

  1. 将气球的坐标按照结束点的大小进行排序。
  2. 设置射击数量变量 c n t cnt cnt 1 1 1,同时设置一个变量 e n d end end 表示当前射击的结束点。
  3. 遍历气球的坐标数组,对于当前的气球坐标 ( s t a r t , e n d start, end start,end):
    • 如果 s t a r t > e n d start > end start>end,表示当前气球的起始点在之前的射击结束点之后,说明需要增加一个射击的数量,同时更新 e n d end end 为当前气球的结束点。
    • 否则,表示当前气球的起始点在之前的射击结束点之前,说明当前气球可以用同一支箭射击,不需要增加射击的数量,但是需要更新 e n d end end 为当前气球的结束点。
  4. 当遍历结束后, c n t cnt cnt 的值即为最少需要的射击数量。

3.3 参考答案

#include <iostream>
#include <algorithm>
using namespace std;int n, cnt = 1;struct Node
{int start, end;
}balloon[1005];bool cmp(Node a, Node b)
{return a.end < b.end;
}int main()
{cin >> n;for (int i = 1; i <= n; i++){cin >> balloon[i].start >> balloon[i].end;}// 按照结束点排序sort(balloon+1, balloon+n+1, cmp);int end = balloon[1].end;for (int i = 2; i <= n; i++){// 如果当前气球起始点再之前的结束点之后if (balloon[i].start > end){cnt++; // 增加射击数量end = balloon[i].end; // 更新射击结束点}}cout << cnt;return 0;
}

彩蛋


下期预告

下期知识点总结(明天)将会给大家刷 7 道很难的题,也就是 魔鬼刷题日

C++玩法技巧

多行输出的时候,用函数 R"()"

cout << R"(####
#**#
#**#
####
…)"

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

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

相关文章

五种多目标优化算法(MOGWO、MOJS、NSWOA、MOPSO、MOAHA)性能对比,包含6种评价指标,9个测试函数(提供MATLAB代码)

一、5种多目标优化算法简介 1.1MOGWO 1.2MOJS 1.3NSWOA 1.4MOPSO 1.5MOAHA 二、5种多目标优化算法性能对比 为了测试5种算法的性能将其求解9个多目标测试函数&#xff08;zdt1、zdt2 、zdt3、 zdt4、 zdt6 、Schaffer、 Kursawe 、Viennet2、 Viennet3&#xff09;&#xff0…

Linux服务器安装MySQL8

进入安装目录 /usr/local下载 wget https://dev.mysql.com/get/Downloads/MySQL-8.0/mysql-8.0.20-linux-glibc2.12-x86_64.tar.xz解压,重命名 tar -Jxvf mysql-8.0.20-linux-glibc2.12-x86_64.tar.xzmv mysql-8.0.20-linux-glibc2.12-x86_64 mysql8创建用户组、用户 # 需要…

fastApi笔记01-路径参数

路径参数 使用与 Python 格式化字符串相同的语法来声明路径"参数"或"变量" from fastapi import FastAPIapp FastAPI()app.get("/items/{item_id}") def read_item(item_id):return {"item_id": item_id} http://127.0.0.1:8000/i…

SpringSecurity安全框架

我们使用这个springSecurity安全框架,作用是认证,授权,将用户的权限和对应的资源进行绑定,默认的是在内存中保存的,实际开发中,是需要根据项目业务的需求对某些方法进行重写,使数据库中权限对应的资源进行绑定,就是查看当前登录的用户所扮演的角色,该角色有哪些权限 授权 1内…

【操作系统】

计算机操作系统 计算机是如何让用户得到好的体验什么是操作系统&#xff08;OS&#xff09;操作系统如何管理 计算机是如何让用户得到好的体验 计算机系统是由计算机硬件和软件组成的。用户使用计算机&#xff0c;比如在文本文件填写内容&#xff0c;通过邮箱发送邮件&#xf…

Aloudata StarRocks 直播预告:指标平台的物化加速实践

数据指标的管理、研发和应用一直存在着诸多痛点&#xff0c;这些挑战促使了对指标平台解决方案的需求不断增长。2月29日&#xff08;星期四&#xff09;19:00&#xff0c;Aloudata 将与 StarRocks 携手举办线上直播&#xff0c;深入揭秘第三代指标平台物化加速的强大能力&#…

大蟒蛇(Python)笔记(总结,摘要,概括)——第10章 文件和异常

目录 10.1 读取文件 10.1.1 读取文件的全部内容 10.1.2 相对文件路径和绝对文件路径 10.1.3 访问文件中的各行 10.1.4 使用文件的内容 10.1.5 包含100万位的大型文件 10.1.6 圆周率中包含你的生日吗 10.2 写入文件 10.2.1 写入一行 10.2.2 写入多行 10.3 异常 10.3.1 处理Ze…

基于springboot+vue的课程答疑系统(前后端分离)

博主主页&#xff1a;猫头鹰源码 博主简介&#xff1a;Java领域优质创作者、CSDN博客专家、阿里云专家博主、公司架构师、全网粉丝5万、专注Java技术领域和毕业设计项目实战&#xff0c;欢迎高校老师\讲师\同行交流合作 ​主要内容&#xff1a;毕业设计(Javaweb项目|小程序|Pyt…

think-cell Round 1 (A~C)

think-cell Round 1 目录&#xff1a;A B C A题&#xff1a;Maximise The Score 标签: 贪心&#xff08;greedy&#xff09;排序&#xff08;sortings&#xff09; 题目大意 有一个长度为 2n&#xff0c;数值为 1 − 1e7 的数组a&#xff0c;可执行如下操作: 每步在a中选择两…

什么是AI、AIGC、PGC、AGI

AI AI&#xff0c;全名 “Artificial Intelligence”&#xff0c;中文为人工智能。 它是研究、开发用于模拟、延伸和扩展人的智能的理论、方法、技术及应用系统的一门新的技术科学。 AIGC &#xff08;Artificial Intelligence Generated Content&#xff09;是人工智能生成…

RAID 故障修复,重启,卸载,备份

RAID 10 故障修复 当 RAID 10 发生故障了一块硬盘怎么办&#xff1f; 1. 模拟挂掉一块硬盘&#xff0c;从RAID 10 的四块硬盘组中&#xff0c;剔除一块硬盘 # 查寻 sd 相关的磁盘 rootlongchi:~# fdisk -l | grep sd[a-z] Disk /dev/sda: 100 GiB, 107374182400 bytes, 20971…

外站群服务器的特性及使用优势

随着互联网的快速发展&#xff0c;站群服务器在网站运营中扮演着越来越重要的角色。相较于国内站群服务器&#xff0c;国外站群服务器因其独特的特性和使用优势&#xff0c;受到了众多网站管理员的青睐。本文将对国外站群服务器的特性及使用优势进行科普介绍。 一、国外站群服务…

【Spring Cloud】实现微服务调用的负载均衡

文章目录 什么是负载均衡自定义实现负载均衡启动shop-product微服务通过nacos查看微服务的启动情况自定义实现负载均衡 基于Ribbon实现负载均衡添加注解修改服务调用的方法Ribbon支持的负载均衡策略通过修改配置来调整 Ribbon 的负载均衡策略通过注入Bean来调整 Ribbon 的负载均…

JS进阶——解构赋值

数组解构 基本&#xff1a; let [a, b, c] [1, 2, 3]; // a 1 // b 2 // c 3 可嵌套 let [a, [[b], c]] [1, [[2], 3]]; // a 1 // b 2 // c 3 可忽略 let [a, , b] [1, 2, 3]; // a 1 // b 3 不完全解构 let [a 1, b] []; // a 1, b undefined 剩余运…

如何创造价值写给自己的笔记

人工智能统领全文 在深入探讨这篇概述之前&#xff0c;我们首先需要理解一个核心观点&#xff1a;生产力的进步与生产关系的变革是相辅相成的。这一点在历史的长河中不断得到验证&#xff0c;从工业时代到信息时代&#xff0c;再到如今由人工智能引领的新时代&#xff0c;每一…

探索D咖智能饮品机器人的工作原理:科技、材料与设计的相互融合

智能饮品机器人是近年来随着人工智能和自动化技术的发展而崭露头角的一种创新产品。它将科技、材料和设计相互融合&#xff0c;为消费者带来了全新的饮品体验。下面D咖来探索智能饮品机器人的工作原理&#xff0c;以及科技、材料和设计在其中的作用。 首先&#xff0c;智能饮品…

Observability:使用 OpenTelemetry 和 Elastic 监控 OpenAI API 和 GPT 模型

作者&#xff1a; 来自 Elastic David Hope ChatGPT 现在非常火爆&#xff0c;甚至席卷了整个互联网。 作为 ChatGPT 的狂热用户和 ChatGPT 应用程序的开发人员&#xff0c;我对这项技术的可能性感到非常兴奋。 我看到的情况是&#xff0c;基于 ChatGPT 的解决方案将会呈指数级…

Docker本地部署Rss订阅工具并实现公网远程访问

文章目录 1. Docker 安装2. Docker 部署Rsshub3. 本地访问Rsshub4. Linux安装Cpolar5. 配置公网地址6. 远程访问Rsshub7. 固定Cpolar公网地址8. 固定地址访问 Rsshub是一个开源、简单易用、易于扩展的RSS生成器&#xff0c;它可以为各种内容生成RSS订阅源。 Rsshub借助于开源社…

如何在OpenWRT安装内网穿透工具实现远程访问本地搭建的web网站界面

文章目录 前言1. 检查uhttpd安装2. 部署web站点3. 安装cpolar内网穿透4. 配置远程访问地址5. 配置固定远程地址 前言 uhttpd 是 OpenWrt/LuCI 开发者从零开始编写的 Web 服务器&#xff0c;目的是成为优秀稳定的、适合嵌入式设备的轻量级任务的 HTTP 服务器&#xff0c;并且和…

【k近邻】Kd树构造与最近邻搜索示例

【k近邻】 K-Nearest Neighbors算法原理及流程 【k近邻】 K-Nearest Neighbors算法距离度量选择与数据维度归一化 【k近邻】 K-Nearest Neighbors算法k值的选择 【k近邻】 Kd树的构造与最近邻搜索算法 【k近邻】 Kd树构造与最近邻搜索示例 近邻法的实现需要考虑如何快速搜索个最…