【POJ 3614 Sunscreen】贪心 优先级队列
2016-05-10 23:43
411 查看
题目链接: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慢一些,不过空间更少。
题意: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 = 2505; const int MAX_L = 2505; 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 = 0; void swap(int& x, int& y){ int tmp = x; x = y; y = tmp; } void insert(int x){ size++; heap[size-1] = x;//目标元素暂时插到末尾 int i = size - 1;//候选目标位置 while(i > 0){ //上滤,反复与父节点比较 int p = (i-1)/2; if(heap[p] > heap[i]){//与父节点违反堆序性时 swap(heap[i], heap[p]);//父节点下沉 i = p; //候选位置攀升 }else break; } } void deleteTop(){ heap[0] = heap[size-1]; size--; int i = 0; //候选目标位置 while(i*2+1 < size){//下滤 int lc = i*2+1; int rc = i*2+2; 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[0]; } int main() { freopen("3614.txt", "r", stdin); scanf("%d%d", &C, &L); for(int i=0; i<C; i++){ scanf("%d%d", &cows[i].min, &cows[i].max); } for(int i=0; i<L; i++){ scanf("%d%d", &lotions[i].spf, &lotions[i].cover); } sort(lotions, lotions+L, cmpL); sort(cows, cows+C, cmpC); int cnt = 0; for(int i=0, j=0; 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 > 0 && size>0){ if(getTop() >= lotions[i].spf){ vol--; cnt++; //printf("add %d\n", getTop()); } deleteTop(); //printf("%d\n", cnt); } } printf("%d\n", cnt); return 0; }
相关文章推荐
- 从 WordCount 到 MapReduce 计算模型
- 设计模式:Factory模式
- mysql设置精度
- 从 WordCount 到 MapReduce 计算模型
- 异常:'NSInvalidArgumentException'
- 基于反射和注解的Bean对应数据库表的自动生成
- 第十周项目2——贮存班长信息的学生类
- AngularJs(一) MVC 模式的应用
- Spark-ML-02-设计机器学习系统
- 专题三 第十二题
- java Switch语句 和 各运算符
- 使用自己的ClassLoader实现热替换
- Java多线程与并发(二)之线程同步
- 距离感染中文版Office还远吗?勒索软件Locky最新传播载体分析
- C++作业5
- 2016年学习Linux决心书(老男孩教育在线课程班第二期)
- Django+Openshift微信公众号开发(二)
- Uva 3902 Network
- Day9
- 53. Maximum Subarray