P4053 [JSOI2007] 建筑抢修
题目描述
小刚在玩 JSOI 提供的一个称之为“建筑抢修”的电脑游戏:经过了一场激烈的战斗,T 部落消灭了所有 Z 部落的入侵者。但是 T 部落的基地里已经有 N 个建筑设施受到了严重的损伤,如果不尽快修复的话,这些建筑设施将会完全毁坏。现在的情况是:T 部落基地里只有一个修理工人,虽然他能瞬间到达任何一个建筑,但是修复每个建筑都需要一定的时间。同时,修理工人修理完一个建筑才能修理下一个建筑,不能同时修理多个建筑。如果某个建筑在一段时间之内没有完全修理完毕,这个建筑就报废了。你的任务是帮小刚合理的制订一个修理顺序,以抢修尽可能多的建筑。
输入格式
第一行,一个整数 N。
接下来 N 行,每行两个整数 T1,T2 描述一个建筑:修理这个建筑需要 T1 秒,如果在 T2 秒之内还没有修理完成,这个建筑就报废了。
输出格式
输出一个整数 S,表示最多可以抢修 S 个建筑。
输入输出样例
输入 #1
4 100 200 200 1300 1000 1250 2000 3200
输出 #1
3
反悔贪心
#include<iostream>
#include<algorithm>
#include<cstring>
#include<cstdlib>
#include<cmath>
#include<vector>
#include<queue>
#include<deque>
#include<stack>
#include<set>
#include<map>
#include<unordered_set>
#include<unordered_map>
#include<bitset>
#include<tuple>
#define inf 72340172838076673
#define int long long
#define endl '\n'
#define F first
#define S second
#define mst(a,x) memset(a,x,sizeof (a))
using namespace std;
typedef pair<int, int> pii;const int N = 200086, mod = 998244353;int n;struct node {int a, b;bool operator<(const node c)const {return b < c.b;}
} e[N];
priority_queue<int> q;void solve() {cin >> n;for (int i = 1; i <= n; i++) {int a, b;cin >> a >> b;e[i] = {a, b};}sort(e + 1, e + n + 1);int ti = 0;for (int i = 1; i <= n; i++) {if (ti + e[i].a <= e[i].b) { //当前时间 + 项目时间 <= 限制时间q.push(e[i].a);ti += e[i].a;} else {//反悔if (q.size() && e[i].a < q.top()) { //可以压缩前面的时间ti -= q.top();q.pop();ti += e[i].a;q.push(e[i].a);}}} cout << q.size() << endl;
}signed main() {ios::sync_with_stdio(false);cin.tie(nullptr), cout.tie(nullptr);int T = 1;
// cin >> T;while (T--) solve();return 0;
}