• 【bzoj1828/Usaco2010 Mar】balloc 农场分配——贪心+差分+优先队列


    Description

    Input

    第1行:两个用空格隔开的整数:N和M * 第2行到N+1行:第i+1行表示一个整数C_i * 第N+2到N+M+1行: 第i+N+1行表示2个整数 A_i和B_i

    Output

    * 第一行: 一个整数表示最多能够被满足的要求数

    Sample Input

    5 4
    1
    3
    2
    1
    3
    1 3
    2 5
    2 3
    4 5

    Sample Output

    3
     

    网上的题解基本都是贪心+线段树,不过有种更加好写的写法→v→
    先把每段区间按照左端点从小到大排序,并且对于原区间的差分数组l++,r+1--。
    最开始ans=m;
    从小到大枚举畜栏,那么now加上当前位置差分的值就是这个点被多少区间覆盖。
    再把以这个点为左端点的区间的右端点放入大根堆中。
    如果发现此畜栏的容纳量小于当前区间数,就从大根堆里取出now-a[i]个右端点,并且把右端点+1的地方差分数组++(相当于放弃这个区间),ans--。
     

    代码:
     1 #include<cstdio>
     2 #include<cstring>
     3 #include<algorithm>
     4 #include<queue>
     5 const int N=1e5+10;
     6 int n,m,a[N],p[N];
     7 struct node{int l,r;}e[N];
     8 bool cmp(node aa,node bb){return aa.l<bb.l;}
     9 int read(){
    10     int ans=0,f=1;char c=getchar();
    11     while(c<'0'||c>'9'){if(c=='-')f=-1;c=getchar();}
    12     while(c>='0'&&c<='9'){ans=ans*10+c-48;c=getchar();}
    13     return ans*f;
    14 }
    15 std::priority_queue<int>q;
    16 int main(){
    17     n=read();m=read();
    18     for(int i=1;i<=n;i++)a[i]=read();
    19     for(int i=1;i<=m;i++){
    20         int l=read(),r=read();e[i]=(node){l,r};
    21         p[l]++;p[r+1]--;
    22     }
    23     std::sort(e+1,e+1+m,cmp);
    24     int now=0,h=1;int ans=m;
    25     for(int i=1;i<=n;i++){
    26         now+=p[i];
    27         while(h<=m&&e[h].l==i)q.push(e[h].r),h++;
    28         while(now>a[i]&&!q.empty()){
    29             int pp=q.top();q.pop();
    30             p[pp+1]++;now--;ans--;
    31         }
    32     }
    33     printf("%d
    ",ans);
    34     return 0;
    35 }
    36 
    bzoj1828
  • 相关阅读:
    MAVEN整理(乘国庆还有时间,停下来整理一下)
    Hadoop Browse the filesystem 无效处理
    分页实现,类似博客园首页的分页
    Hive权限控制和超级管理员的实现
    缓存淘汰算法
    在线制图
    MySQL的Grant命令
    windows10上安装mysql(详细步骤)
    用Redis轻松实现秒杀系统
    redis 学习
  • 原文地址:https://www.cnblogs.com/JKAI/p/7662957.html
Copyright © 2020-2023  润新知