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();
    }
}
posted @ 2026-07-16 08:39  Skyかざまこうと  阅读(4)  评论(0)    收藏  举报