【POJ 3614 Sunscreen】贪心 优先级队列

简介: 题目链接:http://poj.org/problem?id=3614 题意:C头牛去晒太阳,每头牛有自己所限定的spf安全范围[min, max];有L瓶防晒液,每瓶有自己的spf值和容量(能供几头牛用)。

题目链接:http://poj.org/problem?id=3614

题意:C头牛去晒太阳,每头牛有自己所限定的spf安全范围[min, max];有L瓶防晒液,每瓶有自己的spf值和容量(能供几头牛用)。

求这L瓶防晒液最多能让多少头牛安全地晒太阳。

思路:贪心策略,按spf从小到大或从大到小的顺序取出防晒液,供给尽可能多的剩余的牛。

具体如何判断当前这瓶防晒液最多能供给几头牛呢?

以spf从小到大排序所有防晒液为例,可以维护一个小顶堆,每取出一瓶防晒液l,就把剩余的所有min值低于l.spf的牛的max值放入堆中。

接下来在l的容量尚未耗尽时,反复弹出并比较堆顶值与l.spf,若大于l.spf,则 l 消耗1单位的容量供给这头牛,计数值加1;否则这头牛不能被任何防晒液供给(当前spf已经是剩余的最小值,后续不会有更小的)。反复取堆顶元素直至容量耗尽或堆变空。各瓶防晒液的计数值的总和即为答案。

首先需要将防晒液按spf值从小大到排序(O(LlogL)),以及将牛按min值从小到大排序(O(ClogC));然后外层循环对L瓶防晒液进行一遍扫描(O(L)),内层循环每头牛的max必然入堆一次、弹出一次(Ω(C)),所以总的复杂度为O(LlogL + CLogC + LC)。

自己实现的堆,时间上总是比STL的priority_queue慢一些,不过空间更少。

  1 #include <cstdio>
  2 #include <algorithm>
  3 using namespace std;
  4 const int MAX_C = 2505;
  5 const int MAX_L = 2505;
  6 int C, L;
  7 struct Cow
  8 {
  9     int min, max;
 10     Cow& operator = (Cow& c){
 11         min = c.min;
 12         max = c.max;
 13         return *this;
 14     }
 15 }cows[MAX_C];
 16 
 17 struct Lotion
 18 {
 19     int spf,cover;
 20 }lotions[MAX_C];
 21 
 22 bool cmpL(Lotion l1, Lotion l2){
 23     return l1.spf < l2.spf;
 24 }
 25 bool cmpC(Cow c1, Cow c2){
 26     return c1.min < c2.min;
 27 }
 28 
 29 int heap[MAX_C]; //小顶堆
 30 int size = 0;
 31 
 32 void swap(int& x, int& y){
 33     int tmp = x;
 34     x = y;
 35     y = tmp;
 36 }
 37 
 38 void insert(int x){
 39     size++;
 40     heap[size-1] = x;//目标元素暂时插到末尾
 41     int i = size - 1;//候选目标位置
 42     while(i > 0){     //上滤,反复与父节点比较
 43         int p = (i-1)/2;
 44         if(heap[p] > heap[i]){//与父节点违反堆序性时
 45             swap(heap[i], heap[p]);//父节点下沉
 46             i = p; //候选位置攀升
 47         }else break;
 48     }
 49 }
 50 
 51 void deleteTop(){
 52     heap[0] = heap[size-1];
 53     size--;
 54     int i = 0; //候选目标位置
 55     while(i*2+1 < size){//下滤
 56         int lc = i*2+1;
 57         int rc = i*2+2;
 58         int c = lc;
 59         if(rc<size && heap[rc]<heap[lc])
 60             c = rc;
 61         if(heap[c] < heap[i]){
 62             swap(heap[c], heap[i]);//孩子节点攀升
 63             i = c;//候选位置下沉
 64         }else break;
 65     }
 66 }
 67 
 68 int getTop(){
 69     return heap[0];
 70 }
 71 
 72 int main()
 73 {
 74     freopen("3614.txt", "r", stdin);
 75     scanf("%d%d", &C, &L);
 76     for(int i=0; i<C; i++){
 77         scanf("%d%d", &cows[i].min, &cows[i].max);
 78     }
 79 
 80     for(int i=0; i<L; i++){
 81         scanf("%d%d", &lotions[i].spf, &lotions[i].cover);
 82     }
 83     
 84     sort(lotions, lotions+L, cmpL);
 85     sort(cows, cows+C, cmpC);
 86     
 87     int cnt = 0;
 88     for(int i=0, j=0; i<L; i++){
 89         //printf("lotion %d %d\n", lotions[i].spf, lotions[i].cover);
 90         while(j<C && cows[j].min <= lotions[i].spf){
 91             insert(cows[j].max);
 92             j++;
 93             //printf("insert %d\n", cows[j-1].max);
 94         }
 95         int vol = lotions[i].cover;
 96         
 97         while(vol > 0 && size>0){
 98             if(getTop() >= lotions[i].spf){
 99                 vol--;
100                 cnt++;
101                 //printf("add %d\n", getTop());
102             }
103             deleteTop();
104             //printf("%d\n", cnt);
105         }
106     }
107     printf("%d\n", cnt);
108     return 0;
109 }

 

目录
相关文章
|
数据安全/隐私保护
【洛谷 P1928】外星密码 题解(递归+字符串)
外星密码挑战涉及解压缩由重复子串压缩的字符串,如`[3FUN]`代表`FUNFUNFUN`。输入是一行压缩过的字符串,输出是解压缩的结果。代码使用递归方法,遇到`[`读取重复次数并解压下一层,遇到`]`返回当前层结果,否则直接添加字符。样例输入`AC[3FUN]`输出`ACFUNFUNFUN`。处理的数据限制为解压后长度在20000内,最多十重压缩。
248 0
|
机器学习/深度学习 人工智能
P4447 [AHOI2018初中组]分组 详解
小可可的学校信息组总共有n 个队员,每个人都有一个实力值a[i]a[i]。现在,一年一度的编程大赛就要到了,小可可的学校获得了若干个参赛名额,教练决定把学校信息组的nn 个队员分成若干个小组去参加这场比赛。 但是每个队员都不会愿意与实力跟自己过于悬殊的队员组队,于是要求分成的每个小组的队员实力值连续,同时,一个队不需要两个实力相同的选手。举个例子:[1, 2, 3, 4, 5]是合法的分组方案,因为实力值连续;[1, 2, 3, 5]不是合法的分组方案,因为实力值不连续;[0,1,1,2]同样不是合法的分组方案,因为出现了两个实力值为1 的选手。 如果有小组内人数太少,就会因为时间
440 1
P4447 [AHOI2018初中组]分组 详解
|
2天前
|
存储 关系型数据库 分布式数据库
PostgreSQL 18 发布,快来 PolarDB 尝鲜!
PostgreSQL 18 发布,PolarDB for PostgreSQL 全面兼容。新版本支持异步I/O、UUIDv7、虚拟生成列、逻辑复制增强及OAuth认证,显著提升性能与安全。PolarDB-PG 18 支持存算分离架构,融合海量弹性存储与极致计算性能,搭配丰富插件生态,为企业提供高效、稳定、灵活的云数据库解决方案,助力企业数字化转型如虎添翼!
|
13天前
|
弹性计算 关系型数据库 微服务
基于 Docker 与 Kubernetes(K3s)的微服务:阿里云生产环境扩容实践
在微服务架构中,如何实现“稳定扩容”与“成本可控”是企业面临的核心挑战。本文结合 Python FastAPI 微服务实战,详解如何基于阿里云基础设施,利用 Docker 封装服务、K3s 实现容器编排,构建生产级微服务架构。内容涵盖容器构建、集群部署、自动扩缩容、可观测性等关键环节,适配阿里云资源特性与服务生态,助力企业打造低成本、高可靠、易扩展的微服务解决方案。
1286 5
|
12天前
|
机器学习/深度学习 人工智能 前端开发
通义DeepResearch全面开源!同步分享可落地的高阶Agent构建方法论
通义研究团队开源发布通义 DeepResearch —— 首个在性能上可与 OpenAI DeepResearch 相媲美、并在多项权威基准测试中取得领先表现的全开源 Web Agent。
1318 87
|
1天前
|
弹性计算 安全 数据安全/隐私保护
2025年阿里云域名备案流程(新手图文详细流程)
本文图文详解阿里云账号注册、服务器租赁、域名购买及备案全流程,涵盖企业实名认证、信息模板创建、域名备案提交与管局审核等关键步骤,助您快速完成网站上线前的准备工作。
175 82
2025年阿里云域名备案流程(新手图文详细流程)