思路:

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

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

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

\]

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

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

Code:

#include

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 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生成

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