bzoj 1029 建筑抢修

题目大意:

n个建筑,每个建筑有两个值,一个为修它的时间长度 一个为它的截止日期(若超过该日期则无法修建该建筑)

求最多能修多少个建筑

思路:

首先我们可以把它们按照截止日期排序

然后在正常贪心的基础上 做一个优化

我们把已经修过的建筑的修建时间都放到一个队里

每次如果一个建筑不能修

那么我们考虑一下能否把当前的堆顶换成这个建筑

这样就可以省下来时间

 1 #include<iostream>
 2 #include<cstdio>
 3 #include<algorithm>
 4 #include<cstring>
 5 #include<cstdlib>
 6 #include<cmath>
 7 #include<vector>
 8 #include<queue>
 9 #define inf 2147483611
10 #define ll long long
11 #define MAXN 1500000
12 using namespace std;
13 inline ll read()
14 {
15     ll x=0,f=1;char ch=getchar();
16     while(!isdigit(ch)) {if(ch=='-') f=-1;ch=getchar();}
17     while(isdigit(ch)) {x=x*10+ch-'0';ch=getchar();}
18     return x*f;
19 }
20 struct data
21 {
22     int dl,tm;
23     bool operator < (const data &a) const
24     {
25         return dl<a.dl;
26     }
27 }a[MAXN];
28 priority_queue <int> q;
29 int n,now,ans;
30 int main()
31 {
32     n=read();
33     for(int i=1;i<=n;i++) a[i].tm=read(),a[i].dl=read();
34     sort(a+1,a+n+1);
35     for(int i=1;i<=n;i++)
36     {
37         if(now+a[i].tm<=a[i].dl)
38         {
39             now+=a[i].tm;
40             ans++;
41             q.push(a[i].tm);
42         }
43         else if(q.top()>a[i].tm)
44         {
45             now-=q.top(),now+=a[i].tm;
46             q.pop();q.push(a[i].tm);
47         }
48     }
49     printf("%d",ans);
50 }
View Code
posted @ 2017-11-02 20:51  jack_yyc  阅读(166)  评论(0编辑  收藏  举报