[关闭]
@ysner 2018-07-19T07:29:46.000000Z 字数 1098 阅读 2107

[JSOI2007]建筑抢修

贪心


题面

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

解析

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

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

  1. // luogu-judger-enable-o2
  2. #include<iostream>
  3. #include<cstdio>
  4. #include<cstdlib>
  5. #include<cstring>
  6. #include<cmath>
  7. #include<algorithm>
  8. #include<queue>
  9. #define re register
  10. #define il inline
  11. #define ll long long
  12. #define max(a,b) ((a)>(b)?(a):(b))
  13. #define min(a,b) ((a)<(b)?(a):(b))
  14. #define fp(i,a,b) for(re int i=a;i<=b;i++)
  15. #define fq(i,a,b) for(re int i=a;i>=b;i--)
  16. using namespace std;
  17. const int N=2e5+100;
  18. ll n,tot;
  19. struct dat
  20. {
  21. ll t,g;
  22. bool operator < (const dat &o) const {return -t>-o.t;}
  23. }a[N];
  24. priority_queue<dat>Q;
  25. il bool cmp(dat x,dat y){return x.g<y.g;}
  26. il ll gi()
  27. {
  28. re ll x=0,t=1;
  29. re char ch=getchar();
  30. while(ch!='-'&&(ch<'0'||ch>'9')) ch=getchar();
  31. if(ch=='-') t=-1,ch=getchar();
  32. while(ch>='0'&&ch<='9') x=x*10+ch-48,ch=getchar();
  33. return x*t;
  34. }
  35. int main()
  36. {
  37. n=gi();
  38. fp(i,1,n) a[i].t=gi(),a[i].g=gi();
  39. sort(a+1,a+1+n,cmp);
  40. fp(i,1,n)
  41. {
  42. if(tot+a[i].t<=a[i].g) Q.push(a[i]),tot+=a[i].t;
  43. else
  44. {
  45. re int gg=Q.top().t;
  46. if(gg>a[i].t) tot-=gg,Q.pop(),tot+=a[i].t,Q.push(a[i]);
  47. }
  48. }
  49. printf("%lld\n",1ll*Q.size());
  50. return 0;
  51. }
添加新批注
在作者公开此批注前,只有你和作者可见。
回复批注