背包
背包问题用于解决子集权值和问题,一般会有体积等限制
基本模型
- 背包
这个似乎没啥好说的,注意倒序枚举即可
- 完全背包
也没啥好说的,改成正序即可
- 分组背包
注意枚举顺序先组,后倒序体积,最后元素
- 多重背包
这个直接当成分组背包做肯定是吃不消的
一般常见好写的是二进制拆分,即把那么多物品拆分成 个
来记录一下单调队列优化的方法:
首先写出来转移方程:
可以发现每个 的同余系的转移是独立的,首先用前缀和转化为加法形式
即改写为 ,其中 ,典型的滑动窗口了,单调队列来维护
实现见 P1776 宝物筛选
记录一下另一个蓝书上提到的算法,用于 运行 类型的多重背包问题
对于每一种物品,开一个数组 表示到达体积 最少用几个当前种物品,如果能从 个物品转移为零
- 退背包
即遵循怎么来的怎么回去
每次将 复制到 ,然后 即可,注意要正序枚举
注意 以及可行性时均不能使用退背包
- 优化可行性背包
注意到转移方程为 ,那么用 优化成
不用担心 的 问题,会自动省略超出的部分
- 负体积背包
对于负体积的物品,需要改变循环顺序,因为其加减号发生了改变,那么循环顺序相当于还是保证了转移顺序
- 大容量背包
对于容量很大,而物品体积很小的背包,可以先贪心用性价比最高的选择到 的体积,剩余的跑暴力
例题
算是藏得比较深的背包题,要学会转化
CF687C The Values You Can Make
背包问题的变形
设 表示和为 且子集和为 可不可行
那么有两种转移,即每个放入 的数放不放入
那么
以及
可以发现不选完的序列最多一个
那么枚举每一个序列的前几个,和剩下的背包合并
可以发现这个并不能退背包,那么采用类似于 分治的套路,递归左区间则把右区间放入,否则放左区间
大体积背包,数据范围还不能折半搜索
那必然有特殊要求啦,就是
考虑一位一位进行 ,设 表示 的物品的 所占用 体积的背包价值, 表示前 个物品,且相对于第 位体积为 的最大价值
考虑转移, 的转移很常规, 的转移:
相当于是当前位的体积过渡到下一个的过程,一个顶俩
AT4120 [ARC096D] Sweet Alchemy
考虑每次选择一个子树,只要 就可以满足次数条件
此时就变成了一个多重背包问题
可以发现体积很大而价值很小,使用一种非常神奇的方法:
对于每个物品选出 个来跑多重背包的 ,其余的直接性价比排序贪心来选,这样就不会带来整除对答案的影响了
其中需要交换体积和价值的下标
P8392 [BalticOI 2022 Day1] Uplifting Excurs
这个也是类似的问题,可以先通过贪心把值域缩小到 的 范围
有负数时,可以先贪心地把负数都选上,然后最后再在做背包的时候去掉
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· Linux系列:如何用 C#调用 C方法造成内存泄露
· AI与.NET技术实操系列(二):开始使用ML.NET
· 记一次.NET内存居高不下排查解决与启示
· 探究高空视频全景AR技术的实现原理
· 理解Rust引用及其生命周期标识(上)
· 单线程的Redis速度为什么快?
· 展开说说关于C#中ORM框架的用法!
· Pantheons:用 TypeScript 打造主流大模型对话的一站式集成库
· SQL Server 2025 AI相关能力初探
· 为什么 退出登录 或 修改密码 无法使 token 失效