• 【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
    ", 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
    ", 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
    ", getTop());
    102             }
    103             deleteTop();
    104             //printf("%d
    ", cnt);
    105         }
    106     }
    107     printf("%d
    ", cnt);
    108     return 0;
    109 }
  • 相关阅读:
    js 截取指定的字符串
    WebSocket实例 Vue中使用websoket
    Vue 水半球样式、圆形水进度条、在线编辑
    Elasticsearch学习笔记3 -- 文档操作
    Elasticsearch学习笔记2 -- 索引库的操作
    Elasticsearch学习笔记1 -- 安装elasticsearch
    Docker学习笔记5 -- Docker-compose
    Docker学习笔记4 -- Dockerfile
    Docker学习笔记3 -- 数据卷
    Docker学习笔记2 -- 常用命令
  • 原文地址:https://www.cnblogs.com/helenawang/p/5479894.html
Copyright © 2020-2023  润新知