zoukankan      html  css  js  c++  java
  • [JSOI2007]建筑抢修

    https://zybuluo.com/ysner/note/1218492

    题面

    (n)个建筑有维修时间(T_1)开始不可维修时间点(T_2),问最多能修多少建筑。

    • (nleq2*10^5)

    解析

    显然先按(T_2)排序维修,同时维护(-T_1)小根堆。
    能修就加上(T_1),否则如当前(T_1)小于堆顶就不修堆顶建筑转而修当前建筑。
    能修就修,不能修就换。

    然而我一开始弹堆顶的条件是弹完后可修当前建筑,缩小了弹的范围。。。
    注意时刻向最优化。

    // luogu-judger-enable-o2
    #include<iostream>
    #include<cstdio>
    #include<cstdlib>
    #include<cstring>
    #include<cmath>
    #include<algorithm>
    #include<queue>
    #define re register
    #define il inline
    #define ll long long
    #define max(a,b) ((a)>(b)?(a):(b))
    #define min(a,b) ((a)<(b)?(a):(b))
    #define fp(i,a,b) for(re int i=a;i<=b;i++)
    #define fq(i,a,b) for(re int i=a;i>=b;i--)
    using namespace std;
    const int N=2e5+100;
    ll n,tot;
    struct dat
    {
      ll t,g;
      bool operator < (const dat &o) const {return -t>-o.t;}
    }a[N];
    priority_queue<dat>Q;
    il bool cmp(dat x,dat y){return x.g<y.g;}
    il ll gi()
    {
      re ll x=0,t=1;
      re char ch=getchar();
      while(ch!='-'&&(ch<'0'||ch>'9')) ch=getchar();
      if(ch=='-') t=-1,ch=getchar();
      while(ch>='0'&&ch<='9') x=x*10+ch-48,ch=getchar();
      return x*t;
    }
    int main()
    {
      n=gi();
      fp(i,1,n) a[i].t=gi(),a[i].g=gi();
      sort(a+1,a+1+n,cmp);
      fp(i,1,n)
        {
          if(tot+a[i].t<=a[i].g) Q.push(a[i]),tot+=a[i].t;
          else
        {
          re int gg=Q.top().t;
          if(gg>a[i].t) tot-=gg,Q.pop(),tot+=a[i].t,Q.push(a[i]);   
        }
        }
      printf("%lld
    ",1ll*Q.size());
      return 0;
    }
    
  • 相关阅读:
    双循环解决添加列表问题
    贪心算法
    隔板法发红包
    python小兵之时间模块
    开发规范
    python 小兵(12)模块1
    Linux系统
    刷题
    Socket
    栈和队列
  • 原文地址:https://www.cnblogs.com/yanshannan/p/9333667.html
Copyright © 2011-2022 走看看