背包dp进阶
背包dp
01背包#
有若干物品,每个物品只有一个,要么选要么不选,每个物品有 一个容积和价值。
solution:
设 表示当前考虑到第 个物品时,总容积为 V 的最大 价值。每次转移的时候枚举前面的容积和当前物品选或者不选
总复杂度
如果价值较小时,可以考虑将价值放入状态,记录容积的最小值。 滚动数组优化
完全背包#
有若干种物品,每种物品有无限个,每个物品有一个容积和一个价值,在不超过背包大小的情况下放入价值尽可能大的物品
solution:
和 背包一个样,因为 背包避免一个背包选多次,所以就倒序枚举,那完全背包就正序枚举就好了
多重背包#
有若干种物品,每种物品有 个,每个物品有一个容积和一个价值。在不超过背包大小的情况下放入价值尽可能大的物品
solution:
二进制优化:
因为任何数都可以表示成某些 加和来表示,所以把 进行二进制拆分,将 个物品看做一个整体,按照 背包做
for(int i = 1; i <= n; i++){
int num = min(a[i], V / w[i]);
for(int k = 1; num > 0; k <<= 1){
if(k > num) k = num;
num -= k;
for(int j = V; j >= w[i] * k; j--)
f[j] = max(f[j], f[j - w[i] * k] + v[i] * k);
}
}
[HNOI2007] 梦幻岛宝珠#
solution
01背包板子题目,但花费和价值都特别的大,但花费都能表示成 的形式
从题目的特殊条件考虑,我们可以考虑对所有 相同的物品进行背包,再进行合并
这样把每个物品花费的 提出来,花费就可以看做 ,价值不变,直接 背包就好了
这样就可以求出在各种容量下,只放 相同的物品的最大收益
可以理解为给你一个 现在你已经知道在任何容量下只放 这种物品的最大收益
很显然,背包里面不可能只放 相同的物品,那么怎么把 不同的背包进行合并?
令上方求得每类背包为 ,表示对于 为 的物品背包,容量为 的最大价值
再设一个数组 表示使用 为 的物品进行背包, 的价值所占空间为 时,剩余物品剩余物品(即 为 )所占空间为 的最大价值。
考虑转移:
- 因为 所以每一位上的最大容量为
- 上一位拿出来剩下的空间拿给下一位需要 *2(进制向右移)
- 判断第 位是不是 ,也就是再把这一位上的空间加上
最后答案为
消失之物#
solution:
卷积问题:分别预处理一个前缀背包和一个后缀背包
表示前 个物品填满容量为 的背包的方案数
: 表示后 个物品填满容量为 的背包的方案数
复杂度
考虑背包转移式子
如果
每个 都是由 倒序转移过来的,现在去除一个物品那就正序除去这个物品就好了
memcpy(g, f, sizeof f);
for(int j = 1; j <= m; j++){
if(j >= w[i])g[j] = (g[j] - g[j - w[i]] + 10) % 10;
printf("%d", g[j]);
}
P1450[HAOI2008]硬币购物#
solution
暴力直接每天一次多重背包,时间复杂度 ,一周都跑不完
考虑如果没有硬币数量的限制,那就是个完全背包了
换一种想法:所有在限制之内的方案数 = 所有方案数 - 不合法的方案数
一种神奇的思想:
考虑对一枚硬币限制
假设一个货币一次购买的使用上限为 , 我们现在让它使用 次,用剩下的其他硬币对 的空间跑完全背包,那么跑出来的方案就都是不合法的,那么合法的方案数就是总的方案数减去跑出来的方案数,这就是对一枚硬币的限制情况
对四枚硬币限制:
直接用 减去分别对四种硬币的限制情况??
显然不对,当对一个硬币起限制情况的时候,减去了这个硬币超过范围的情况,但也可能减去对其他硬币超过范围的情况
所以应该为容斥:
根据Y_B_Y 的博客 理解==
怎么求?
- 把式子抄上去,打表计算
- 发现集合里面是个全排列,可以直接二进制枚举
BZOJ4976宝石镶嵌#
有 个物品,每个物品价值依次为 背包容量为 ,价值为背包中的所有物品价值按位或的结果,求怎样使得价值最大
solution
考虑如果 ,那么我们对于每一位都选一个对应位为 的宝石即可。
只需要考虑 的情况,即
直接背包, 表示或为 的时候所需要的最小的数
时间复杂度:
for (int i = 1;i <= n; i++)
for (int j = (1 << 17);j>=0;j++)
f[i + 1][j | w[i]] = min([f[i+1][j | w[i]], f[i][j]+1)
for (int i = (1 << 17);i > 0; i--)
if (f[n + 1][i] <= n - k) printf("%d",f[n + 1][i]);
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· go语言实现终端里的倒计时
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· ollama系列1:轻松3步本地部署deepseek,普通电脑可用
· 按钮权限的设计及实现
· 25岁的心里话