【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慢一些,不过空间更少。

  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 }
时间: 2024-11-23 05:57:12

【POJ 3614 Sunscreen】贪心 优先级队列的相关文章

POJ 2431 Expedition 贪心 优先级队列

Expedition Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 30702   Accepted: 8457 Description A group of cows grabbed a truck and ventured on an expedition deep into the jungle. Being rather poor drivers, the cows unfortunately managed t

poj -3614 Sunscreen(贪心 + 优先队列)

http://poj.org/problem?id=3614 有c头奶牛在沙滩上晒太阳,每头奶牛能忍受的阳光强度有一个最大值(max_spf) 和最小值(min_spf),奶牛有L种防晒霜,每种可以固定阳光强度在某一个值,每种的数量是cover[i] ,每头奶牛只能用一瓶防晒霜,问最多有多少头奶牛能在沙滩上晒太阳. 理解题意之后还是挺好做的. 首先确定的贪心策略是,在满足min_spf的条件下,尽量用spf小的用在max_spf大的奶牛身上,用一个最小堆维护max_spf的最小值即可. 先对奶牛

POJ 3614 Sunscreen(贪心)

POJ 3614 Sunscreen 题目链接 题意:转自http://blog.csdn.net/sdj222555/article/details/10698641 有C个奶牛去晒太阳 (1 <=C <= 2500),每个奶牛各自能够忍受的阳光强度有一个最小值和一个最大值,太大就晒伤了,太小奶牛没感觉. 而刚开始的阳光的强度非常大,奶牛都承受不住,然后奶牛就得涂抹防晒霜,防晒霜的作用是让阳光照在身上的阳光强度固定为某个值. 那么为了不让奶牛烫伤,又不会没有效果. 给出了L种防晒霜.每种的数

POJ 3614 Sunscreen 优先队列

http://poj.org/problem?id=3614 题目大意: 给你一些母牛,母牛有能容忍日光浴的最小和最大光照强度.每仅仅母牛能够涂一次SPF,SPF能够将母牛能够承受的光照强度固定在某个地方.如今给你母牛的最小和最大值和不同的spf的光照强度及其数量,求最多能够有多少母牛享受日光浴? 思路: 优先队列. 先按母牛最小承受的排好,然后spf的值也从小到大. 接下来用优先队列(栈顶为最小的).对于每一个spf,假设一仅仅母牛的最小值小于等于spf则将其最大值入队.(贪心..如两个母牛一

POJ 2431 Expedition (贪心 + 优先级队列)

Expedition Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 7696   Accepted: 2260 Description A group of cows grabbed a truck and ventured on an expedition deep into the jungle. Being rather poor drivers, the cows unfortunately managed to

POJ 3253 Fence Repair 贪心 优先级队列

Fence Repair Time Limit: 2000MS   Memory Limit: 65536K Total Submissions: 77001   Accepted: 25185 Description Farmer John wants to repair a small length of the fence around the pasture. He measures the fence and finds that he needs N (1 ≤ N ≤ 20,000)

BNUOJ 44662 水题 (贪心+优先级队列)

水题 Time Limit: 500ms Memory Limit: 32768KB This problem will be judged on HRBUST. Original ID: 2223 64-bit integer IO format: %lld      Java class name: Main Prev Submit Status Statistics Discuss Next 因为是有关于接水的问题,便简称为水题了(. N个人排队在M个出水口前接水,第i个人接水需时为t[i

poj 3614 Sunscreen 网络流或二分图多重匹配或优先队列

题意: 有C头牛,每头牛有它可以接受的药的最小值和最大值,有L瓶药,每瓶药有一个值u和它最多能给v头牛用,求最多有多少头牛能满足. 分析: 网络流或二分图多重匹配或优先队列,这道题优化了我的dinic模板,原来的模板会TLE... 代码: //poj 3614 //sep9 #include <iostream> #include <queue> #include <algorithm> using namespace std; const int maxN=5005;

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 w