The main problem: N buildings need to be urgently repaired. The first building needs T1 time to repair. The repair must be completed before T2 time. Find out how many buildings can be repaired
First we sort the T2, and then we fix it, but this greed is obviously wrong. For example, this set of data:
5
10 10
10 20
2 21
2 21
2 21
Greed can only repair the first two. And can actually repair up to 4
So we're thinking about fixing the greedy algorithm
Let's say this set of data, when we enumerate to 3. Although there is no way to repair many others, we can cancel the repair of the building 1 and Repair 3. This saves time in the back of the building, even though you can't update ans.
So that's a pretty clear idea.
We maintain a large pile, and every building we repair, we add the T1 value of the building to the heap. If we can't fix it now, we can infer that the top of the heap is bigger than the T1 assumption of the building. Cancel the repair heap top. Repair the current building instead
#include <cstdio> #include <cstring> #include <iostream> #include <algorithm> #define M 150100using namespace Std;struct construction{int T1,t2;bool operator < (const construction &x) Const{return T2 < ; X.t2;}} Buildings[m];int n,ans,now,heap[m],top;void Insert (int x) {Heap[++top]=x;int t=top;while (t>1&&heap[t] >HEAP[T>>1]) swap (heap[t],heap[t>>1]), t>>=1;} void Pop () {heap[1]=heap[top--];int t=2;while (t<=top) {if (t<top&&heap[t+1]>heap[t]) ++t;if (Heap[t] >HEAP[T>>1]) swap (heap[t],heap[t>>1]), T<<=1;elsebreak;}} int main () {int i;cin>>n;for (i=1;i<=n;i++) scanf ("%d%d", &buildings[i]. T1,&buildings[i]. T2); sort (buildings+1,buildings+n+1); for (i=1;i<=n;i++) {if (Now+buildings[i]. T1<=buildings[i]. T2) {Now+=buildings[i]. T1;++ans;insert (Buildings[i]. T1);} Else{if (!top) continue;int temp=heap[1];if (Temp>buildings[i]. T1) Now=now+buildings[i]. T1-temp,pop (), Insert (Buildings[i]. T1);}} Cout<<ans&lT;<endl;}
Bzoj 1029 JSOI2007 Construction Repair greedy + heap