CF2182E New Year's Gifts 贪心
CF2182E New Year's Gifts
题目大意
你有\(n\)个朋友,\(m\)个礼物盒,\(k\)块钱,每个礼物盒的美观度为\(a_i\),对于第\(i\)个朋友,必须给TA \(y_i\)元,当 TA 满足以下两个条件之一时,会感到开心。
- 收到一个美观度 \(\ge x_i\)
- 获得至少 \(z_i\) 元
要求最大化满足条件开心的朋友。
思路:
首先,每个人都要满足获得的钱\(\ge y_i\),所以我们考虑先把这部分解决掉。我们只要把 \(k\) 减去 \(\sum_{i=1}^{n}{y_i}\) 就行了。
其次,我们考虑对于每一个礼物,它可以使那些\(x_i\)比\(a_i\)小的人开心。我们把朋友按 \(x_i\) 从小到大排序,以\(a_x\)从小到大枚举每个礼物。当他的美观度满足了一个朋友,我们就认为他可以被礼物搞定,而我们每个礼物不用想肯定要用得最划算,把要花钱最多的那个带走。使用priority_queue维护可以被当前礼物和以前的礼物搞定的朋友的花费的最大值(前面按\(y_i\)排序的用处,维持单调性),每次把花费最大的那个pop掉,就可以了。
然后我们还剩下一些朋友(包括了priority_queue里面没带走的和不能用礼物带走的那些),我们就用钱搞定他们。剩下的就是很明显的贪心(从小到大依次搞定,知道钱不够了)。
代码(C++)
/*
@ Author: Eric / Sky__White
@ Filename: CF2182E.cpp
@ Date: 12/07/2026
@ Email: acwing@foxmail.com / 17802535158@163.com
*/
#include <cstring>
#include <iostream>
#include <algorithm>
#include <vector>
#include <functional>
#include <cstdio>
#include <queue>
namespace std {
class Read {
public:
template<typename T>
inline Read operator >> (T & x) {
T sum = 0, opt = 1;
char ch = getchar();
while(!isdigit(ch)) opt = (ch == '-') ? -1 : 1, ch = getchar();
while( isdigit(ch)) sum = (sum << 1) + (sum << 3) + (ch ^ 48), ch = getchar();
x = sum * opt; return *this;
}
};
}
#define int long long
#define all(a) a.begin(), a.end()
using namespace std; Read fin;
void solve() {
int n, m, k; fin >> n >> m >> k;
vector<int> arr(m + 1);
for (int i = 1; i <= m; i ++ )
fin >> arr[i];
struct Node {
int x, y, z;
}; vector<Node> fri(n + 1);
for (int i = 1; i <= n; i ++ ) {
fin >> fri[i].x >> fri[i].y >> fri[i].z;
k -= fri[i].y;
}
sort(1 + all(arr));
priority_queue<int> q;
sort(1 + all(fri), [&](Node a, Node b) {
return a.x < b.x;
});
int opt = 1, res = 0;
for (int i = 1; i <= m; i ++ ) {
while (opt <= n and fri[opt].x <= arr[i])
q.push(fri[opt].z - fri[opt].y), opt ++ ;
if (q.size())
q.pop(), res ++ ;
// cout << i << " " << q.size() << endl;
}
while(opt <= n) {
q.push(fri[opt].z - fri[opt].y), opt ++ ;
}
priority_queue<int, vector<int>, greater<int> > q2;
while(q.size()) {
q2.push(q.top()), q.pop();
}
while(q2.size()) {
// cout << k << " ";
k -= q2.top();
// cout << k << endl;
if (k < 0) break;
res ++ ; q2.pop();
}
cout << res << endl;
}
signed main() {
int T; fin >> T;
while(T -- ) {
solve();
}
}

浙公网安备 33010602011771号