其實對於這一題可以使用貪心,而且很好證明正確性。
假設維修所需時間是Si,限時是Ti。
首先,我們對T進行排序,然後這個時候序列就有下面的特性了。
假如T3的時候可以維修3個,也就是說 ,那好如果S4進來了,
但是S1+S2+S3+S4卻大於T4,那麼我們是不是直接丟棄掉T4呢?其實不行,因為如果S4比起前面的如果小一點,那麼當然要把S4進行兌換,把耗時高一點的去掉。
這裡就會出現一個問題,你這樣換能保證正確性嗎?絕對能。
我們知道 並且如果T3前能完成3個就說明
那麼就繼續照著上面說的兌換做一做數學推導。
從這裡我們可以知道從時間消耗小了,但是能維修的房子數量卻沒有少。
#include <iostream>
#include <queue>
#include <algorithm>
#define MAXN 200200
using namespace std;
int n, T = 0, ans = 0;
struct node{
int s, t;
}a[MAXN];
priority_queue<int> q;
bool cmp(node x, node y){
return x.t < y.t;
}
int main(){
cin >> n;
for(int i = 1; i <= n; i++){
cin >> a[i].s >> a[i].t;
}
sort(a + 1, a + n + 1, cmp);
for(int i = 1; i <= n; i++){
if(T + a[i].s > a[i].t){
if(a[i].s < q.top()){
T -= q.top();
q.pop();
q.push(a[i].s);
T += a[i].s;
}
}
else{
q.push(a[i].s);
ans++;
T += a[i].s;
}
}
cout << ans;
}