POJ 3614 Sunscreen(贪心 优先队列)有助于理解贪心过程

2023-10-17 09:38

本文主要是介绍POJ 3614 Sunscreen(贪心 优先队列)有助于理解贪心过程,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

题目链接

Description
To avoid unsightly burns while tanning, each of the C (1 ≤ C ≤ 2500) cows must cover her hide with sunscreen when they’re at the beach. Cow i has a minimum and maximum SPF rating (1 ≤ minSPFi ≤ 1,000; minSPFi ≤ maxSPFi ≤ 1,000) that will work. If the SPF rating is too low, the cow suffers sunburn; if the SPF rating is too high, the cow doesn’t tan at all…
The cows have a picnic basket with L (1 ≤ L ≤ 2500) bottles of sunscreen lotion, each bottle i with an SPF rating SPFi (1 ≤ SPFi ≤ 1,000). Lotion bottle i can cover coveri cows with lotion. A cow may lotion from only one bottle.
What is the maximum number of cows that can protect themselves while tanning given the available lotions?
Input
Line 1: Two space-separated integers: C and LLines 2…C+1: Line i describes cow i’s lotion requires with two integers: minSPFi and maxSPFi
Lines C+2…C+L+1: Line i+C+1 describes a sunscreen lotion bottle i with space-separated integers: SPFi and coveri
Output
A single line with an integer that is the maximum number of cows that can be protected while tanning
Sample Input
3 2
3 10
2 5
1 5
6 2
4 1
Sample Output
2

题目大意:
有C头牛,每个牛都有对阳光的承受空间[minspf, maxspf],有L种防晒霜,每种都对应有SPF值和瓶数,涂到牛身上可使其只受到SPF值的阳光,每瓶只可涂一头牛,问最多几只牛可以享受阳光。

解题思路:
此题可以视为在数轴上对区间进行操作:
在这里插入图片描述
上图中两头牛的防嗮区间分别为[1,4]和[2,3]
1、当防晒霜值为1时,只能给牛1用;
2、当防晒霜值为3时,牛1和牛2都有需求,那么我们应该给牛2,因为从图上看,牛2已经马上承受不住了,所以我们先给最大承受值较小的那头牛,再看看有没有适合牛1的;
3、当防晒霜值为4时,只能给牛1用。

下面来总结一下我们的贪心策略:
1、将牛的右边界从大到小排序;
2、将防晒霜按spf值从小到大排序;

对于排好序的牛,对于当前考虑的牛,假设有两瓶防晒霜 x < y可选,那么我们选x,因为x,y对于后面的牛来说有三种情况:

①x、y可选

②x不可选,y可选

③x、y均不可选

那么我们选择小的(即x)就对后面的牛来说影响最小

AC代码(贪心):

#include<iostream>
#include<stdio.h>
#include<algorithm>
using namespace std;
struct cow {int minnum, maxnum;
}list1[2501];
struct fangshaishuang {int v, num;
}list2[2501];
bool cmp1(cow a, cow b) { return a.maxnum < b.maxnum; }
bool cmp2(fangshaishuang a, fangshaishuang b) {return a.v < b.v;
}int main() {int n, m;scanf("%d%d", &n, &m);for (int i = 1; i <= n; i++) {scanf("%d%d", &list1[i].minnum, &list1[i].maxnum);}for (int i = 1; i <= m; i++) {scanf("%d%d", &list2[i].v, &list2[i].num);}sort(list1 + 1, list1 + 1 + n, cmp1);sort(list2 + 1, list2 + 1 + m, cmp2);int ans = 0;for (int i = 1; i <= n; i++) {for (int j = 1; j <= m; j++) {if (list2[j].v >= list1[i].minnum&&list2[j].v <= list1[i].maxnum&&list2[j].num > 0) {ans++; list2[j].num--;break;}}}cout << ans << endl;
}

解题过程中也参考了很多大神们的博客,发现有好多大神都选择了优先队列的写法:

将奶牛按照防晒范围的最小值升序排序,将防晒霜的值也进行升序排序,从最小的防晒霜值开始考虑,将最小值小于等于该防晒霜值的奶牛拿出来,把它们区间的右边界放入优先队列之中(优先队列中最小值先出),就可将这些右边界中最小的取出来,更新答案。

优先队列写法:
AC代码

#include<iostream>
#include<queue>
#include<functional>
#include<algorithm>
using namespace std;struct cow {int l, r;
}list1[2501];
struct suns {int v, num;
}list2[2501];
bool cmp1(cow a, cow b) { return a.l < b.l; }
bool cmp2(suns a, suns b) { return a.v < b.v; }
priority_queue<int, vector<int>, greater<int> > que;
int main() {int c, l;cin >> c >> l;for (int i = 1; i <= c; i++) { cin >> list1[i].l >> list1[i].r; }for (int i = 1; i <= l; i++) { cin >> list2[i].v >> list2[i].num; }sort(list1 + 1, list1 + 1 + c, cmp1);sort(list2 + 1, list2 + 1 + l, cmp2);int j = 1;//从第一头牛开始考虑int ans = 0;for (int i = 1; i <= l; i++) {//对每一种防晒霜进行考虑while (j <= c&&list1[j].l <= list2[i].v) {//将所有左边界小于防晒霜值的牛的右边界都压进优先队列que.push(list1[j].r);j++;}while (list2[i].num > 0 && !que.empty()) {int tmp = que.top();que.pop();if (tmp >= list2[i].v) {//如果当前右边界最小的牛可以用list2[i].num--;ans++;}}}cout << ans << endl;
}

这篇关于POJ 3614 Sunscreen(贪心 优先队列)有助于理解贪心过程的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/224519

相关文章

从原理到实战深入理解Java 断言assert

《从原理到实战深入理解Java断言assert》本文深入解析Java断言机制,涵盖语法、工作原理、启用方式及与异常的区别,推荐用于开发阶段的条件检查与状态验证,并强调生产环境应使用参数验证工具类替代... 目录深入理解 Java 断言(assert):从原理到实战引言:为什么需要断言?一、断言基础1.1 语

SpringBoot整合liteflow的详细过程

《SpringBoot整合liteflow的详细过程》:本文主要介绍SpringBoot整合liteflow的详细过程,本文给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋...  liteflow 是什么? 能做什么?总之一句话:能帮你规范写代码逻辑 ,编排并解耦业务逻辑,代码

Java中调用数据库存储过程的示例代码

《Java中调用数据库存储过程的示例代码》本文介绍Java通过JDBC调用数据库存储过程的方法,涵盖参数类型、执行步骤及数据库差异,需注意异常处理与资源管理,以优化性能并实现复杂业务逻辑,感兴趣的朋友... 目录一、存储过程概述二、Java调用存储过程的基本javascript步骤三、Java调用存储过程示

MySQL中的InnoDB单表访问过程

《MySQL中的InnoDB单表访问过程》:本文主要介绍MySQL中的InnoDB单表访问过程,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录1、背景2、环境3、访问类型【1】const【2】ref【3】ref_or_null【4】range【5】index【6】

浏览器插件cursor实现自动注册、续杯的详细过程

《浏览器插件cursor实现自动注册、续杯的详细过程》Cursor简易注册助手脚本通过自动化邮箱填写和验证码获取流程,大大简化了Cursor的注册过程,它不仅提高了注册效率,还通过友好的用户界面和详细... 目录前言功能概述使用方法安装脚本使用流程邮箱输入页面验证码页面实战演示技术实现核心功能实现1. 随机

Navicat数据表的数据添加,删除及使用sql完成数据的添加过程

《Navicat数据表的数据添加,删除及使用sql完成数据的添加过程》:本文主要介绍Navicat数据表的数据添加,删除及使用sql完成数据的添加过程,具有很好的参考价值,希望对大家有所帮助,如有... 目录Navicat数据表数据添加,删除及使用sql完成数据添加选中操作的表则出现如下界面,查看左下角从左

CSS3打造的现代交互式登录界面详细实现过程

《CSS3打造的现代交互式登录界面详细实现过程》本文介绍CSS3和jQuery在登录界面设计中的应用,涵盖动画、选择器、自定义字体及盒模型技术,提升界面美观与交互性,同时优化性能和可访问性,感兴趣的朋... 目录1. css3用户登录界面设计概述1.1 用户界面设计的重要性1.2 CSS3的新特性与优势1.

canal实现mysql数据同步的详细过程

《canal实现mysql数据同步的详细过程》:本文主要介绍canal实现mysql数据同步的详细过程,本文通过实例图文相结合给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的... 目录1、canal下载2、mysql同步用户创建和授权3、canal admin安装和启动4、canal

MySQL存储过程之循环遍历查询的结果集详解

《MySQL存储过程之循环遍历查询的结果集详解》:本文主要介绍MySQL存储过程之循环遍历查询的结果集,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录前言1. 表结构2. 存储过程3. 关于存储过程的SQL补充总结前言近来碰到这样一个问题:在生产上导入的数据发现

SpringBoot集成LiteFlow实现轻量级工作流引擎的详细过程

《SpringBoot集成LiteFlow实现轻量级工作流引擎的详细过程》LiteFlow是一款专注于逻辑驱动流程编排的轻量级框架,它以组件化方式快速构建和执行业务流程,有效解耦复杂业务逻辑,下面给大... 目录一、基础概念1.1 组件(Component)1.2 规则(Rule)1.3 上下文(Conte