https://www.luogu.com.cn/problem/P4053
题意:
给 n 个建筑,每个建筑有一个维修时间 T1,如果在 T2 时间内还没维修完,就报废了,只能一个一个维护建筑,问最多为维修几个建筑
样例:
4 100 200 200 1300 1000 1250 2000 3200
3
思路:
将所有建筑按照报废时间排序,然后一次遍历,如果可以修的话一定要修,并把修这个建筑需要的时间 T1 放进优先队列维护
如果修不了的话,判断 修这个建筑的时间 和 堆顶元素(之前修建筑的最大时间),如果比之前时间小的话,进行反悔操作,即不修之前的那个建筑,改修现在的建筑,由于按照报废时间排序,当前建筑一定不会报废,实现反悔贪心。
代码:
#include<bits/stdc++.h>
#define endl '\n'
#define debug(x) cout<<#x<<" = "<<x<<endl;
using namespace std;
typedef long long ll;
typedef pair<ll,ll> pii;
#define int long long
void solve(){
int n;
cin>>n;
vector<pii>a(n+1);
for(int i=1;i<=n;i++){
cin>>a[i].first>>a[i].second;
}
sort(a.begin()+1,a.end(),[&](pii aa,pii bb){return aa.second<bb.second;});
int ans=0,now=0;
priority_queue<int>pq;
for(int i=1;i<=n;i++){
int t1=a[i].first,t2=a[i].second;
if(now+t1<=t2){
ans++;
now+=t1;
pq.push(t1);
}
else if(t1<pq.top()){
int t=pq.top();
pq.pop();
now-=t;
now+=t1;
pq.push(t1);
}
}
cout<<ans<<endl;
}
signed main(){
ios::sync_with_stdio(0);
cin.tie(0);
cout.tie(0);
int T=1;
// cin>>T;
while(T--){
solve();
}
return 0;
}