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

相关文章

MyBatis-Plus逻辑删除实现过程

《MyBatis-Plus逻辑删除实现过程》本文介绍了MyBatis-Plus如何实现逻辑删除功能,包括自动填充字段、配置与实现步骤、常见应用场景,并展示了如何使用remove方法进行逻辑删除,逻辑删... 目录1. 逻辑删除的必要性编程1.1 逻辑删除的定义1.2 逻辑删php除的优点1.3 适用场景2.

Java 队列Queue从原理到实战指南

《Java队列Queue从原理到实战指南》本文介绍了Java中队列(Queue)的底层实现、常见方法及其区别,通过LinkedList和ArrayDeque的实现,以及循环队列的概念,展示了如何高效... 目录一、队列的认识队列的底层与集合框架常见的队列方法插入元素方法对比(add和offer)移除元素方法

JAVA SpringBoot集成Jasypt进行加密、解密的详细过程

《JAVASpringBoot集成Jasypt进行加密、解密的详细过程》文章详细介绍了如何在SpringBoot项目中集成Jasypt进行加密和解密,包括Jasypt简介、如何添加依赖、配置加密密钥... 目录Java (SpringBoot) 集成 Jasypt 进行加密、解密 - 详细教程一、Jasyp

Java通过ServerSocket与Socket实现通信过程

《Java通过ServerSocket与Socket实现通信过程》本文介绍了Java中的ServerSocket和Socket类,详细讲解了它们的构造方法和使用场景,并通过一个简单的通信示例展示了如何... 目录1 ServerSocket2 Socket3 服务器端4 客户端5 运行结果6 设置超时总结1

GO语言zap日志库理解和使用方法示例

《GO语言zap日志库理解和使用方法示例》Zap是一个高性能、结构化日志库,专为Go语言设计,它由Uber开源,并且在Go社区中非常受欢迎,:本文主要介绍GO语言zap日志库理解和使用方法的相关资... 目录1. zap日志库介绍2.安装zap库3.配置日志记录器3.1 Logger3.2 Sugared

MongoDB搭建过程及单机版部署方法

《MongoDB搭建过程及单机版部署方法》MongoDB是一个灵活、高性能的NoSQL数据库,特别适合快速开发和大规模分布式系统,本文给大家介绍MongoDB搭建过程及单机版部署方法,感兴趣的朋友跟随... 目录前言1️⃣ 核心特点1、文档存储2、无模式(Schema-less)3、高性能4、水平扩展(Sh

深入理解Redis线程模型的原理及使用

《深入理解Redis线程模型的原理及使用》Redis的线程模型整体还是多线程的,只是后台执行指令的核心线程是单线程的,整个线程模型可以理解为还是以单线程为主,基于这种单线程为主的线程模型,不同客户端的... 目录1 Redis是单线程www.chinasem.cn还是多线程2 Redis如何保证指令原子性2.

深入理解MySQL流模式

《深入理解MySQL流模式》MySQL的Binlog流模式是一种实时读取二进制日志的技术,允许下游系统几乎无延迟地获取数据库变更事件,适用于需要极低延迟复制的场景,感兴趣的可以了解一下... 目录核心概念一句话总结1. 背景知识:什么是 Binlog?2. 传统方式 vs. 流模式传统文件方式 (非流式)流

深入理解Go之==的使用

《深入理解Go之==的使用》本文主要介绍了深入理解Go之==的使用,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧... 目录概述类型基本类型复合类型引用类型接口类型使用type定义的类型不可比较性谈谈map总结概述相信==判等操作,大

MySQL中存储过程(procedure)的使用及说明

《MySQL中存储过程(procedure)的使用及说明》存储过程是预先定义的SQL语句集合,可在数据库中重复调用,它们提供事务性、高效性和安全性,MySQL和Java中均可创建和调用存储过程,示例展... 目录概念示例1示例2总结概念存储过程:在数据库中预先定义好一组SQL语句,可以被程序反复调用。