题解:P11328 [NOISG 2022 Finals] Gym Badges
swate114514 · · 题解
模拟赛的题,反悔了但是排序顺序猜错了。喜提 wa85……
首先我们可以用邻项交换法来确定排序顺序。
| 交换前 | 交换后 |
|---|---|
- 设交换前第
i 次可以参加比赛,第i+1 次不可以参加比赛。 - 而交换后更优,第
i 和i+1 次都可以参加比赛。
只要
我们知道,若
同理,若
于是条件成了:
把
整理可得
于是
所以按
然后就比较套路了,当前这一个比赛无法满足时,显然替换掉前面比赛中
/*
Code by swate114514.
*/
#include <bits/stdc++.h>
#define int long long
using namespace std;
inline int read() {int s = 0, w = 1;char ch = getchar();while (ch > '9' || ch < '0') {if (ch == '-') w *= -1;ch = getchar();}while (ch >= '0' && ch <= '9') {s = (s << 3) + (s << 1) + (ch ^ 48);ch = getchar();}return s * w;}
inline void write(int x) {if (x < 0) putchar('-'), x = -x;if (x > 9) write(x / 10);putchar(x % 10 + '0');}
const int N = 1e5 + 5;
int n;
struct node {
int h, p;
bool operator < (const node& b) {
return h + p < b.h + b.p;
}
} a[N];
priority_queue<int> qu;
signed main() {
freopen("invader.in", "r", stdin);
freopen("invader.out", "w", stdout);
n = read();
for (int i = 1; i <= n; ++i) a[i] = {read(), read()};
sort(a + 1, a + n + 1);
int cnt = 0, tot = 0;
for (int i = 1; i <= n; ++i) {
if (tot > a[i].h) {
if (!qu.empty() && qu.top() > a[i].p) {
cnt--, tot -= qu.top();
qu.pop();
}
}
if (tot <= a[i].h) {
cnt++;
tot += a[i].p;
qu.push(a[i].p);
}
}
write(cnt);
return 0;
}
::::