题意(我把房子改成作业吧,好理解),有n项作业,每个作业有要花费的时间t1,和deadline t2,问最多能写几个作业。
首先,假如每样作业花费的时间都是一样的,那肯定按哪一个作业deadline比较近(t2比较小)先做哪一个,对吧
但是问题话费的时间不一样,那怎么办呢,我们先按第一种理论来,t2小的先做,然后发现有作业要完不成了(前面花费的时间加上自己要花费的时间超过deadline了)
这时候就有了一个万全的策略,我看看前面写完的作业里,花费时间最多的作业用了多少时间,如果这个时间比当前作业还多,那么我完全可以不做之前那个作业,而做现在这个
作业(反正我当前作业deadline比较晚,所以可以替换,而且花的时间又少)。
//
// main.cpp
// Problem : [JSOI2007]建筑抢修
//
// Created by czf on 2016/11/5.
// Copyright © 2016年 czf. All rights reserved.
//
#include <algorithm>
#include <iostream>
#include <cstdio>
#include <queue>
using namespace std;
typedef long long LL;
const int MAXN = 150000 + 100;
struct P {
LL t1, t2;
bool operator < (const P &rhs) const {
return t1 < rhs.t1;
}
};
bool cmp(const P &lhs, const P &rhs) {
if (lhs.t2 == rhs.t2) return lhs.t1 < rhs.t1;
return lhs.t2 < rhs.t2;
}
P a[MAXN];
int main() {
int n;
while (scanf("%d",&n) == 1) {
for (int i = 0; i < n; i ++) {
scanf("%lld%lld",&a[i].t1,&a[i].t2);
}
sort(a, a+n, cmp);
priority_queue<P> q;
LL sum = 0, cnt = 0;
for (int i = 0; i < n; i ++) {
if (a[i].t1 + sum <= a[i].t2) {
sum += a[i].t1;
cnt ++;
q.push(a[i]);
} else if(!q.empty()) {
if (a[i].t1 < q.top().t1) {
sum -= q.top().t1;
sum += a[i].t1;
q.pop();
q.push(a[i]);
}
}
}
printf("%lld\n",cnt);
}
return 0;
}