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

相关文章

Spring boot整合dubbo+zookeeper的详细过程

《Springboot整合dubbo+zookeeper的详细过程》本文讲解SpringBoot整合Dubbo与Zookeeper实现API、Provider、Consumer模式,包含依赖配置、... 目录Spring boot整合dubbo+zookeeper1.创建父工程2.父工程引入依赖3.创建ap

Linux下进程的CPU配置与线程绑定过程

《Linux下进程的CPU配置与线程绑定过程》本文介绍Linux系统中基于进程和线程的CPU配置方法,通过taskset命令和pthread库调整亲和力,将进程/线程绑定到特定CPU核心以优化资源分配... 目录1 基于进程的CPU配置1.1 对CPU亲和力的配置1.2 绑定进程到指定CPU核上运行2 基于

深入理解Go语言中二维切片的使用

《深入理解Go语言中二维切片的使用》本文深入讲解了Go语言中二维切片的概念与应用,用于表示矩阵、表格等二维数据结构,文中通过示例代码介绍的非常详细,需要的朋友们下面随着小编来一起学习学习吧... 目录引言二维切片的基本概念定义创建二维切片二维切片的操作访问元素修改元素遍历二维切片二维切片的动态调整追加行动态

Java进程异常故障定位及排查过程

《Java进程异常故障定位及排查过程》:本文主要介绍Java进程异常故障定位及排查过程,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录一、故障发现与初步判断1. 监控系统告警2. 日志初步分析二、核心排查工具与步骤1. 进程状态检查2. CPU 飙升问题3. 内存

从原理到实战深入理解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完成数据添加选中操作的表则出现如下界面,查看左下角从左