[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;
}
后记
(没有任何辱骂,诋毁的意思,只是客观评价)关于这篇题解
- 做法是错的
- 题解疑似AI生成
希望作者尽快删除或或修正,避免误导他人。

浙公网安备 33010602011771号