Loading

P3188 [HNOI2007] 梦幻岛宝珠

喷一下洛谷题解。

很多老题,充斥着远古时期的,过分复杂的题解。

往往在一个本不难的题上花费大量时间的经历比比皆是。

希望未来的付费模式,会有强力的 LLM 答疑,或者题解更严格的审核机制,现状真的害人不浅。

题意

01 背包,但是所有体积和价值 \(\le 10^9\)。物品的体积表示成 \(a \cdot 2 ^ b\) 后,可以保证 \(a \le 10\)\(b \le 30\)

思路

如果没有物品体积的保证,那这题应该不是很可做。

于是,我们将背包分层:\(f(i,j)\) 代表只考虑 \(b = i\) 的所有数,\(\sum a \le j\) 的可以得到的最大收益。

同一层可以直接 01 背包转移,每一层时间是 \(\mathcal{O}(n \times \max a)\),接下来就是合并的事。

显然,我们可以,也必须要逐位枚举的(因为体积上限也很大)。因为大空间数量换算成小空间数量不需要除法,那么我们从大到小考虑。

(我们将体积上限记作 \(W\)

\(g(i,j)\) 代表处理完了 \(b > i\) 的情况,正在处理 \(b = i\) 的情况,\(W\)\(b \ge i\) 的部分还剩 \(j\)\(2 ^ i\) 可以用。

如果在 \(b = i\) 这一层我们选取 \(f(i,k)\)。那么剩余的 \(2^i\) 份数还剩 \(j - k\),下放到更低一层就是 \(2(j - k)\) 了。

因此,我们如果让 \(W\) 的二进制第 \(i - 1\) 位(0-indexed)是 \(c\) 的话,那么转移为 \(g(i - 1, 2(j - k) + c) \leftarrow g(i,j) + f(i,k)\) 了。

至此,我们利用了物品体积的特殊性质,分层完成了一次 01 背包。

posted @ 2026-07-25 19:22  Trent900  阅读(28)  评论(0)    收藏  举报