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 }