【算法笔记】背包模板-算法详解
01背包
有 件物品和一个容量为 的背包。第 件物品所耗费的空间是 ,得到的价值是 。求解将哪些物品装入背包可使价值总和最大。
- “求什么设什么”,我们用 表示前 件物品耗费空间为 可得到的最大价值。显然,答案是 。
- 那么状态转移方程呢?思考一下。对于第 件物品,有取和不取两种情况。
- 如果当前这件物品不取,那么其实前 件物品耗费的总空间就是 ,得到的价值不变;
- 如果当前这件物品取,那么前 件物品耗费的总空间就是 ,得到的价值就是 ;
- 所以可得转移方程:
- 不过,二维的空间,是不是有些浪费?
- 其实,我们可以省去 这一维,那么转移方程就变成了:
- 不过,省去了这一维,就出现了一个细节需要注意:要倒叙枚举 ,而不是正序枚举,因为正序枚举在枚举 时 已经被覆盖过了,那么就有可能取过了第 件物品,不满足动态规划的特性:无后效性。(自己手动推一下,会更理解)
完全背包
有 件物品和一个容量为 的背包,每件物品都有无限件。放入 第 件物品耗费的空间是 ,得到的价值是 。求解将哪些物品放入背包可使价值总和最大;
- 可得转移方程
- 完全背包怎么压缩空间呢?其实就是 背包的代码,把 改成正序枚举就好了。为什么可以这样做?
- 因为完全背包可以取无限次,枚举 前第 件物品能够已经取过,符合完全背包
多重背包
有 种物品和一个容量为 的背包。第i种物品最多有 件可用,每件费用是 ,价值是 。求解将哪些物品装入背包可使这些物品的费用总和不超过背包容量,且价值总和最大。
- 我们可以用暴力的方法枚举,对于第i种物品有 种策略:取 件,取 件……取 件,
- 可是这种方法会超时 ,所以我们要用二进制优化
- 以下是一种简洁的方法:
二维费用背包
对于每件物品,具有两种不同的费用;选择这件物品必须同时付出这两种代价;对于每种代价都有一个可付出的最大值(背包容量)。问怎样选择物品可以得到最大的价值。设这两种代价分别为代价和代价,第件物品所需的两种代价分别为 和 。两种代价可付出的最大值(两种背包容量)分别为和。物品的价值为。
- 费用加了一维,只要状态也加一维即可;
- 状态转移方程:
- 同样,可以压缩空间:
分组背包
有 件物品和一个容量为 的背包。第i件物品的费用是 ,价值是。这些物品被划分为若干组,每组中的物品互相冲突,最多选一件。求解将哪些物品装入背包可使这些物品的费用总和不超过背包容量,且价值总和最大。
- 其实对于这种题目,我们只是多一重循环枚举组中的物品,这个问题变成了每组物品有若干种策略:是选择本组的某一件,还是一件都不选。具体看代码;
01背包
有 件物品和一个容量为 的背包。第 件物品所耗费的空间是 ,得到的价值是 。求解将哪些物品装入背包可使价值总和最大。
- “求什么设什么”,我们用 表示前 件物品耗费空间为 可得到的最大价值。显然,答案是 。
- 那么状态转移方程呢?思考一下。对于第 件物品,有取和不取两种情况。
- 如果当前这件物品不取,那么其实前 件物品耗费的总空间就是 ,得到的价值不变;
- 如果当前这件物品取,那么前 件物品耗费的总空间就是 ,得到的价值就是 ;
- 所以可得转移方程:
- 不过,二维的空间,是不是有些浪费?
- 其实,我们可以省去 这一维,那么转移方程就变成了:
- 不过,省去了这一维,就出现了一个细节需要注意:要倒叙枚举 ,而不是正序枚举,因为正序枚举在枚举 时 已经被覆盖过了,那么就有可能取过了第 件物品,不满足动态规划的特性:无后效性。(自己手动推一下,会更理解)
完全背包
有 件物品和一个容量为 的背包,每件物品都有无限件。放入 第 件物品耗费的空间是 ,得到的价值是 。求解将哪些物品放入背包可使价值总和最大;
- 可得转移方程
- 完全背包怎么压缩空间呢?其实就是 背包的代码,把 改成正序枚举就好了。为什么可以这样做?
- 因为完全背包可以取无限次,枚举 前第 件物品能够已经取过,符合完全背包
多重背包
有 种物品和一个容量为 的背包。第i种物品最多有 件可用,每件费用是 ,价值是 。求解将哪些物品装入背包可使这些物品的费用总和不超过背包容量,且价值总和最大。
- 我们可以用暴力的方法枚举,对于第i种物品有 种策略:取 件,取 件……取 件,
- 可是这种方法会超时 ,所以我们要用二进制优化
- 以下是一种简洁的方法:
二维费用背包
对于每件物品,具有两种不同的费用;选择这件物品必须同时付出这两种代价;对于每种代价都有一个可付出的最大值(背包容量)。问怎样选择物品可以得到最大的价值。设这两种代价分别为代价和代价,第件物品所需的两种代价分别为 和 。两种代价可付出的最大值(两种背包容量)分别为和。物品的价值为。
- 费用加了一维,只要状态也加一维即可;
- 状态转移方程:
- 同样,可以压缩空间:
分组背包
有 件物品和一个容量为 的背包。第i件物品的费用是 ,价值是。这些物品被划分为若干组,每组中的物品互相冲突,最多选一件。求解将哪些物品装入背包可使这些物品的费用总和不超过背包容量,且价值总和最大。
- 其实对于这种题目,我们只是多一重循环枚举组中的物品,这个问题变成了每组物品有若干种策略:是选择本组的某一件,还是一件都不选。具体看代码;
__EOF__
本文链接:https://www.cnblogs.com/Michael-zx/p/12334836.html
关于博主:评论和私信会在第一时间回复。或者直接私信我。
版权声明:本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!
声援博主:如果您觉得文章对您有帮助,可以点击文章右下角【推荐】一下。您的鼓励是博主的最大动力!
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 开发者必知的日志记录最佳实践
· SQL Server 2025 AI相关能力初探
· Linux系列:如何用 C#调用 C方法造成内存泄露
· AI与.NET技术实操系列(二):开始使用ML.NET
· 记一次.NET内存居高不下排查解决与启示
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· 没有Manus邀请码?试试免邀请码的MGX或者开源的OpenManus吧
· 园子的第一款AI主题卫衣上架——"HELLO! HOW CAN I ASSIST YOU TODAY
· 【自荐】一款简洁、开源的在线白板工具 Drawnix