有 n 个盒子,初始第 i 个盒子里有 ai 个球。两种操作:取一个球,代价为 1;选择 m 个编号连续的盒子,取出总计不超过 k 个球,代价为 c。问取走所有球需要消耗的最小代价。(1<=m<=n<=5e5,1<=c<=k<=1e9,ai<=1e9)(部分分 c=1)
注意本题解只是我的个人记录,目的并不是教会人做此类题。相反,要学会做,必须独立思考并证明。
c=1
c=1 考虑贪心:从第一个盒子开始向右,取出 d=min(k,ai)
个球,ai-=d
,k-=d
,k 不为 0 且还未取 m 个连续盒子则继续,否则答案累加上 c,再新开一个区间。
贪心可以感性证明正确性。由于题目相当于“选择 m 个编号连续的盒子,取出总计 d<=k 个球,价值为 max(d-c,0)。最大化价值。”取满 k 个一定优,靠前取也更利于后面再取。
反过来考虑,这种贪心不优是因为没有取满,即当前长为 m 的区间内球数过少。
性质
为了进一步做,证明一些重要性质,存在至少一个最优解满足:
任意两区间交最多为 1
对于你取的 m 个编号连续的盒子中取了至少一个的盒子,下面所说的“区间”指最小的能完全覆盖这些盒子的区间。
不妨设 a<b。
调整 a 块为红,b 块的其中 a 块为黄,即任意两区间交最多为 1。这有利于至少一个区间向外扩展,故必不劣。
任意两长度 >=2 区间交点,一定取满
反正也是不取,取 b 而不取 a 也使答案不劣,且靠前取也更利于后面再取。
任意两长度 >=2 区间交点,其中长为 1 的区间,一定取满 k 个。
扩展蓝块,缩小黄块,直至蓝块达到 k 个,或黄块完全退出此堆。双方均有利。
任意长度 >=3 区间中,除两端点外,只由此区间占据,且一定取完。
调整是不难的。后者也易证。
DP
形式非常明确。从一个点开始,运行贪心,一旦遇到没有取满 k 个的情况,要么取(此时区间内全取完),要么不取(此时这个区间的左端点可以不取完,从“左端点+1”及以后选一个点开始贪)。
这就是分阶段 DP。
平方 DP:https://qoj.ac/submission/863322
如果注意到了,从一个点 x 开始,运行贪心,没有取满 k 个的情况,所在的转移点只有 O(1) 个,就能优化了。
问题在于求转移点。
一个长为 m 的区间,从左到右取不满 k 个,就是最左边的盒子一直 k 个 k 个地取,取到 <k 个,然后它和右边 m-1 个盒子的和 <k。条件写出来就是:
- 右边 m-1 个盒子的和 s<k
- 左边第一个盒子模 k 小于 k-s
推广,假设从 i 开始从左往右取,到 j 时 [j,j+m-1] 取不满 k 个,就是 i 到 j 的和模 k 小于 k-s。
用前缀和改写一下就是 si 模 k 位于环上一个区间内。
这可以扫一遍,用区间覆盖线段树维护。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· ollama系列1:轻松3步本地部署deepseek,普通电脑可用
· 按钮权限的设计及实现
· 【杂谈】分布式事务——高大上的无用知识?