「JSOI2007」建筑抢修

传送门
Luogu

解题思路

显然先把所有楼按照报废时间递增排序。
然后考虑 \(1\cdots i-1\) 都能修完, \(i\) 修不完的情况。
显然我们在这 \(i\) 个里面至多只能修 \(i-1\)
那么我们把前 \(i\) 中最耗费时间的不修,只修剩下的 \(i-1\) 个,就可以省出后面的时间。

细节注意事项

  • 咕咕咕

参考代码

#include <algorithm>#include <iostream>#include <cstring>#include <cstdlib>#include <cstdio>#include <cctype>#include <cmath>#include <ctime>#include <queue>#define rg registerusing namespace std;template < typename T > inline void read(T& s) { s = 0; int f = 0; char c = getchar(); while (!isdigit(c)) f |= c == '-', c = getchar(); while (isdigit(c)) s = s * 10 + (c ^ 48), c = getchar(); s = f ? -s : s;}typedef long long LL;const int _ = 150010;int n; struct node{ LL dlt, lim; }t[_];inline bool cmp(const node& a, const node& b) { return a.lim < b.lim; }priority_queue < LL > Q;int main() {#ifndef ONLINE_JUDGE freopen("in.in", "r", stdin);#endif read(n); for (rg int i = 1; i <= n; ++i) read(t[i].dlt), read(t[i].lim); sort(t + 1, t + n + 1, cmp); LL T = 0; int ans = 0; for (rg int i = 1; i <= n; ++i) { if (T + t[i].dlt > t[i].lim) { if (t[i].dlt < Q.top()) { T -= Q.top(), Q.pop(); T += t[i].dlt, Q.push(t[i].dlt); } } else T += t[i].dlt, Q.push(t[i].dlt), ++ans; } printf("%d\n", ans); return 0;}

完结撒花 \(qwq\)

相关文章