93pts求调!悬1关
查看原帖
93pts求调!悬1关
759274
Stevehim楼主2023/10/18 20:23
#include <bits/stdc++.h>
#define int long long
#define maxn 50010
using namespace std;
/*
	c_i 排序
  设当前选完k个总和为sum
  k + 1 - np最小的
  考虑从已经选的里面拿出一个点b
  当前选定一个点a
  那么选的就是 Sum - c_b + c_a + p_b
  于是最小化(p_b + c_a - c_b)
  即最小化(p_b - c_b) + c_a
  其实就不用开三个小根堆

*/

struct node {
	int p, c, pos;
	bool operator < (const node &b) const {
		return c > b.c;
	}
} a[maxn];

struct node2 {
	int cha, pos, c, p;
	bool operator < (const node2 &b) const {
		return cha > b.cha;
	}
};


bool cmp(node a, node b) {
	return a.p < b.p;
}
bool vis[maxn];
priority_queue<node> q;
priority_queue<node2> q1;
int n, k;
int m;
int ans;
signed main() {
	scanf("%lld %lld %lld", &n, &k, &m);
	for (int i = 1; i <= n; i++) {
		scanf("%lld %lld", &a[i].p, &a[i].c);
		a[i].pos = i;
		q.push(a[i]);
	}
	memset(vis, false, sizeof vis);
	while (k--) {
		m -= q.top().c;
		if (m <= 0) {
			break;
		} else vis[q.top().pos] = true, ans++, q1.push({q.top().p - q.top().c, q.top().pos, q.top().c, q.top().p});
		q.pop();
	}
	if (m < 0) {
		printf("%lld", ans);
		return 0;
	}
	sort(a + 1, a + 1 + n, cmp);
	for (int i = 1; i <= n; i++) {
		if (vis[a[i].pos]) continue;
		//或者min(p_a, p_b - c_b + c_a)
		if (q1.size() &&  a[i].p >= q1.top().p - q1.top().c + q.top().c) {
			m -= q1.top().p - q1.top().c + q.top().c;
			if (m >= 0) q1.pop(), q.pop(), ans++, i--;
			else break;
		} else {
			m -= a[i].p;
			q.pop(), q1.pop();
			if (m > 0) ans++;
			else break;
		}

	}
	cout << ans;
	return 0;
}
2023/10/18 20:23
加载中...