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]\) 的最优解更劣(证明略)。因此这种处理方式不会影响最终的答案。
再补一个 \(dp\) 做法:
先将物品按 \(b[i]\) 升序排序。
设 \(dp[i][j]\):考虑前 \(i\) 个物品,且第 \(i\) 个物品一定选,共选 \(j\) 个物品,最小总代价。
\(init: dp[i][1] = a[i]\)
\(trans:\)
\(ans: \max(j)[dp[i][j] <= L]\)
上式中的最小值式子可以用小根堆动态维护,复杂度 \(O(n^{2}logn)。\)
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· ollama系列01:轻松3步本地部署deepseek,普通电脑可用
· 按钮权限的设计及实现
· 25岁的心里话