【POJ 3614 Sunscreen】贪心 优先级队列
题目链接: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慢一些,不过空间更少。
#include <cstdio>
#include <algorithm>
using namespace std;
const int MAX_C = ;
const int MAX_L = ;
int C, L;
struct Cow
{
int min, max;
Cow& operator = (Cow& c){
min = c.min;
max = c.max;
return *this;
}
}cows[MAX_C]; struct Lotion
{
int spf,cover;
}lotions[MAX_C]; bool cmpL(Lotion l1, Lotion l2){
return l1.spf < l2.spf;
}
bool cmpC(Cow c1, Cow c2){
return c1.min < c2.min;
} int heap[MAX_C]; //小顶堆
int size = ; void swap(int& x, int& y){
int tmp = x;
x = y;
y = tmp;
} void insert(int x){
size++;
heap[size-] = x;//目标元素暂时插到末尾
int i = size - ;//候选目标位置
while(i > ){ //上滤,反复与父节点比较
int p = (i-)/;
if(heap[p] > heap[i]){//与父节点违反堆序性时
swap(heap[i], heap[p]);//父节点下沉
i = p; //候选位置攀升
}else break;
}
} void deleteTop(){
heap[] = heap[size-];
size--;
int i = ; //候选目标位置
while(i*+ < size){//下滤
int lc = i*+;
int rc = i*+;
int c = lc;
if(rc<size && heap[rc]<heap[lc])
c = rc;
if(heap[c] < heap[i]){
swap(heap[c], heap[i]);//孩子节点攀升
i = c;//候选位置下沉
}else break;
}
} int getTop(){
return heap[];
} int main()
{
freopen("3614.txt", "r", stdin);
scanf("%d%d", &C, &L);
for(int i=; i<C; i++){
scanf("%d%d", &cows[i].min, &cows[i].max);
} for(int i=; i<L; i++){
scanf("%d%d", &lotions[i].spf, &lotions[i].cover);
} sort(lotions, lotions+L, cmpL);
sort(cows, cows+C, cmpC); int cnt = ;
for(int i=, j=; i<L; i++){
//printf("lotion %d %d\n", lotions[i].spf, lotions[i].cover);
while(j<C && cows[j].min <= lotions[i].spf){
insert(cows[j].max);
j++;
//printf("insert %d\n", cows[j-1].max);
}
int vol = lotions[i].cover; while(vol > && size>){
if(getTop() >= lotions[i].spf){
vol--;
cnt++;
//printf("add %d\n", getTop());
}
deleteTop();
//printf("%d\n", cnt);
}
}
printf("%d\n", cnt);
return ;
}
【POJ 3614 Sunscreen】贪心 优先级队列的更多相关文章
- POJ 3614 Sunscreen 贪心
题目链接: http://poj.org/problem?id=3614 Sunscreen Time Limit: 1000MSMemory Limit: 65536K 问题描述 to avoid ...
- POJ 2431 Expedition 贪心 优先级队列
Expedition Time Limit: 1000MS Memory Limit: 65536K Total Submissions: 30702 Accepted: 8457 Descr ...
- poj -3614 Sunscreen(贪心 + 优先队列)
http://poj.org/problem?id=3614 有c头奶牛在沙滩上晒太阳,每头奶牛能忍受的阳光强度有一个最大值(max_spf) 和最小值(min_spf),奶牛有L种防晒霜,每种可以固 ...
- POJ 3253 Fence Repair 贪心 优先级队列
Fence Repair Time Limit: 2000MS Memory Limit: 65536K Total Submissions: 77001 Accepted: 25185 De ...
- HDU 6709“Fishing Master”(贪心+优先级队列)
传送门 •参考资料 [1]:2019CCPC网络选拔赛 H.Fishing Master(思维+贪心) •题意 池塘里有 n 条鱼,捕捉一条鱼需要花费固定的 k 时间: 你有一个锅,每次只能煮一条鱼, ...
- The 10th Shandong Provincial Collegiate Programming Contest H.Tokens on the Segments(贪心+优先级队列 or 贪心+暴力)
传送门 •题意 二维平面上有 n 条线段,每条线段坐标为 $(l_i,i),(r_i,i)$: 平面上的每个整点坐标上都可以放置一枚硬币,但是要求任意两枚硬币的横坐标不相同: 问最多有多少条线段可以放 ...
- HDU 6438"Buy and Resell"(贪心+优先级队列)
传送门 •参考资料 [1]:HDU6438(优先队列+思维) •题意 有n个城市,第 i 天你会达到第 i 个城市: 在第 i 个城市中,你可以用 ai 元购买一个物品,或者用 ai 元卖掉一个物品, ...
- Sunscreen POJ - 3614(贪心)
To avoid unsightly burns while tanning, each of the C (1 ≤ C ≤ 2500) cows must cover her hide with s ...
- 优先队列:POJ No 3614 Sunscreen 贪心
Sunscreen Time Limit: 1000MS Memory Limit: 65536K Total Submissions: 6410 Accepted: 2239 Descrip ...
随机推荐
- SignalR在Xamarin Android中的使用
原文:SignalR在Xamarin Android中的使用 ASP.NET SignalR 是为 ASP.NET 开发人员提供的一个库,可以简化开发人员将实时 Web 功能添加到应用程序的过程.实时 ...
- CSS发光边框文本框效果
7,166 次阅读 ‹ NSH Blog 网页设计 CSS发光边框文本框效果 或许你看过Safari浏览器下,任何输入框都会有一个发光的蓝色边框,这不单纯只是蓝色边框而已,其实包含了许多CSS3技巧知 ...
- mongoDB global,startUplog
1,show logs (Ruiy看到一些人干些事就跟拉shit一样(磨叽),就来气,娃儿的,还不知所谓,抱怨,叫器一大堆!!!,喝喝,就这它还三心二意学一个故事中的主人公小小明上课偷打`皮卡`玩,三 ...
- Android专项面试训练题(一)
1.下面不可以退出Activity的是?(D) A.finish() B.抛异常强制退出 C.System.exit(0) D.onStop() 解析: A, finish() 方法就是退出activ ...
- Oracle学习笔记(2)——过程和函数
过程和函数统称为PL/SQL子程序,通过输入.输出参数或输入/输出参数与其调用者交换信息.他们是被命名的PL/SQL块,被编译后存储在数据库中,以备执行.因此,可以在数据库中直接按名称使用它们. 1. ...
- A Simple Problem with Integers(100棵树状数组)
A Simple Problem with Integers Time Limit: 5000/1500 MS (Java/Others) Memory Limit: 32768/32768 K ...
- 使用Xcode上传代码至GitHub
几乎所有iOS程序员都上过GitHub寻找开源类库,的确,GitHub上有大量优秀的开源类库供大家学习.但是如何在Xcode中上传代码至GitHub呢? (开始之前先安装git,具体方法这里讲的很清楚 ...
- ExtJs4.0入门错误
当在eclipse中的web工程中增加了extjs4,出现An internal error occurred during: "Building workspace". Java ...
- latex 固定图片位置
1,插入并列的子图 \usepackage{subfigure} \begin{figure}[H] \centering \subfigure[SubfigureCaption]{ \label{F ...
- RabbitMQ消息队列安装和配置以及推送消息
好久没有写了,最近项目用到RabbitMQ,找了一些资料试验,最后终于成功了,把安装配置的步骤分享给大家. 一.Erlang安装具体过程: 1.双击otp_win32_R16801.exe(不同版本可 ...