[NOIP2025] 糖果店 / candy 题解

思路:

杂话:第一眼感觉和 CSP-S 的第一题的思路很像。

很显然,买的每种糖果的数量不是奇数就是偶数,于是可以得到下面的式子:

\[ C = 2 \times x + y (x \in \mathbb{N}, y\in {0,1}) \]

考虑贪心,因为 \(x\) 有多种选择,所以我们先贪偶数个的,然后再看要不要补一个。

但是我们又发现,可能有时补两个单个的也许比直接买了一个两个的更划算,于是把买了偶数的个数和价值记下来,从大往小返回,记录能增加的个数即可。

Code:

#include <bits/stdc++.h>
using namespace std;
using ll = long long;
constexpr int MAXN = 1e5 + 5;
struct node
{
    ll val, type;
    bool operator<(const node &b) const
    {
        return type == b.type ? val < b.val : type > b.type;
    }
} candy[MAXN << 1];
ll n, m;
struct node2
{
    ll val, cnt;
    bool operator<(const node2 &b) const
    {
        return val < b.val;
    }
};
priority_queue<node2> que;
ll ans;
int main()
{
    cin >> n >> m;
    ll a, b;
    for (int i = 1; i <= n; ++i)
        cin >> a >> b, candy[i * 2 - 1] = {a + b, 2}, candy[i * 2] = {a, 1};
    sort(candy + 1, candy + 2 * n + 1);

    for (int i = 1; i <= n; ++i)
    {
        ll cnt = m / candy[i].val;
        ans += cnt * 2;
        m -= cnt * candy[i].val;
        if (cnt)
            que.push((node2){candy[i].val, cnt});
    }
    ll sum = 0, add = 0;
    for (int i = n + 1; i <= 2 * n; ++i)
    {
        while (m < candy[i].val && !que.empty())
        {
            auto u = que.top();
            que.pop();
            // long double nee
            // if (u.val == 0)
            //     exit(1);
            ll tag = (candy[i].val - m + u.val - 1) / u.val;
            tag = min(u.cnt, tag);
            sum -= 2 * tag, m += u.val * tag;
            u.cnt -= tag;
            if (u.cnt)
                que.push(u);
        }
        if (m >= candy[i].val)
            ++sum, m -= candy[i].val;
        add = max(add, sum);
    }
    cout << add + ans;
    return 0;
}

后记

(没有任何辱骂,诋毁的意思,只是客观评价)关于这篇题解

  1. 做法是错的
  2. 题解疑似AI生成

希望作者尽快删除或或修正,避免误导他人。

posted @ 2025-11-29 18:33  孤独的Bochi  阅读(19)  评论(0)    收藏  举报