3.6——932C

932C#

限时每日一题day11。这回是思路对了,但不会实现。看完讨论区后才发现这题有个很巧妙的地方,可以避免复杂维护。

不难想到对于所有选择的物品,一定是按照 \(b[i]\) 的大小升序排列是最优的。此时 \(b\) 的贡献为:\(max(b[i]) - min(b[i])\)

将所有物品按 \(b\) 升序排列,则可以 \(O(n^{2})\) 枚举区间 \([l,r]\),让 \(b[l] = min(b), b[r] = max(b)\),这样剩下的物品只能在 \((l, r)\)中选,且不需要考虑它们 \(b[i]\) 的影响。

那么显然,要在规定总体积范围内最大化选择物品数量,一定是贪心地先选取 \(a[i]\) 更小的物品。

此时棘手的事情出现了——若每次固定 \(l\),枚举 \(r\) 时,钦定选择 \(l\)\(r\) 位置的物品,则规定总体积将是不确定的。因为能保证 \(b[r] - b[l]\) 的值单调递增,但是 \(a\) 的变化是增是减并不确定。因此在规定总体积的变化趋势不定的情况下,并不好维护上述信息(反正我是没想到)。

后来去这场的评论区看了下,发现了一个很巧妙的处理方式,可以让上述的规定总体积变化趋势固定:就是对于 \(l\)\(r\) 处的两个物品,先不钦定选择它们,并且计入它们 \(b\) 值的贡献,而不计入 \(a\) 值的贡献。这样就能保证规定总体积在 \(r\) 右移过程中一定是单调递减的。此时就可以用大根堆来维护 \([l,r]\) 内所有物品的 \(a[i]\),并根据规定的总体积来适时弹出堆顶。由于规定总体积单调递减,可以保证每个物品最多进出堆一次,因此可以保证 \(O(n^{2}logn)\) 的复杂度。

那么这样处理为什么可行呢?巧妙之处来了:这样处理看似有出入的地方在于,可能没有选择物品 \(l\) 或物品 \(r\) ,而计入了 \(b[l]\)\(b[r]\),导致实际总价值计算得不对。但是这对于得到这道题的答案是没有影响的。因为在没有选物品 \(l\) 的情况下,\([l + 1,r]\) 的最优解一定不会比此时的 \([l, r]\) 的最优解更劣。同理在没有选物品 \(r\) 的情况下,\([l,r - 1]\) 的最优解也一定不会比此时的 \([l, r]\) 的最优解更劣(证明略)。因此这种处理方式不会影响最终的答案。

code

再补一个 \(dp\) 做法:

先将物品按 \(b[i]\) 升序排序。

\(dp[i][j]\):考虑前 \(i\) 个物品,且第 \(i\) 个物品一定选,共选 \(j\) 个物品,最小总代价。

\(init: dp[i][1] = a[i]\)

\(trans:\)

\[dp[i][j] = \min_{k=1}^{i-1}(dp[k][j-1] - b[k]) + a[i] + b[i] \]

\(ans: \max(j)[dp[i][j] <= L]\)

上式中的最小值式子可以用小根堆动态维护,复杂度 \(O(n^{2}logn)。\)

code2

posted @   jxs123  阅读(2)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· ollama系列01:轻松3步本地部署deepseek,普通电脑可用
· 按钮权限的设计及实现
· 25岁的心里话
点击右上角即可分享
微信分享提示
主题色彩