背包DP
问题描述
基本背包问题
背包问题(Knapsack Problem)描述的是有容量约束的情况下,求考虑了所有物品(大小价值各异)之后的最优解或解的个数。[背包问题九讲]
首先来总结,如果我们要求的是背包中能装的最大价值。我们用以下变量来表示:
:物品 的大小
:物品 的价值
背包总容量
表示容量为 的背包的答案,最后返回答案 。
两种基本的背包问题:
0-1背包:每个物品只能拿一次
完全背包:每个物品能拿无限次
背包方法
转移方程(空间压缩后)
容量的遍历顺序
0-1背包
完全背包
# 0-1背包:因为利用到本行信息,倒序保证安全更新
for n in nums:
for j in range(V, n-1, -1):
# 完全背包:因为利用到上一行信息,正序保证及时更新
for n in nums:
for j in range(n, V+1):在循环中是业务逻辑,有时候我们不是求最大最小值,而是求可行性或者方案数。
其中0-1背包和完全背包的转移方程是一样的,唯一区别是容量变量 的遍历方向。
遍历方向解释
能够这样做的原因是因为转移方程依赖哪一行的结果,之后我们看了二维(空间压缩前的转移方程)就明白了,图示如下:

0-1背包:因为利用到本行信息,倒序保证安全更新
完全背包:因为利用到上一行信息,正序保证及时更新
初始化 有两种情况:
求背包中能装的最大价值,初始
求装满背包的最大价值,初始
或者可行性解决初始化:
可以这么考虑:考虑了0个物品后,什么都不装 = 装满容量为0的背包
延伸背包问题
多维费用背包:如果背包有多种容量限制(比如长和宽),每个物品有多个维度体积,那么可以“费用“这个维度可以扩展开来。如果每个物品只能拿一次,维度=2,那么就是二维费用0-1背包问题,
分组背包:如果所有物品被划分成 组,每组最多只能拿一个物品
背包方法
转移方程(空间压缩后)
容量的遍历顺序
二维0-1背包
分组背包
例题
0-1背包
空间压缩前的转移方程:
目标和:转化问题以后为0-1背包方案数问题。每个物品只能拿一次,有几种装满背包的方案?
分割等和子集:转化后为0-1背包可行性问题。每个物品只能拿一次,是否能正好装满背包。
最后一块石头的重量 II:转化后为0-1背包最小值问题。
有一堆石头,每块石头的重量都是正整数。
每一回合,从中选出任意两块石头,然后将它们一起粉碎。假设石头的重量分别为 x 和 y,且 x <= y。那么粉碎的可能结果如下:
如果 x == y,那么两块石头都会被完全粉碎;
如果 x != y,那么重量为 x 的石头将会完全粉碎,而重量为 y 的石头新重量为 y-x。
最后,最多只会剩下一块石头。返回此石头最小的可能重量。如果没有石头剩下,就返回 0。
完全背包
空间压缩前的转移方程:唯一的区别在于拿了物品 以后不急着增加 ,因为你还有机会拿。
二维费用0-1背包
01 字符构成最多的字符串:多维费用的 0-1 背包最大值,有两个背包大小,0 的数量和 1 的数量。
盈利计划:多维费用的 0-1 背包最大值
分组背包
掷骰子的N种方法:每一组是一个骰子,每个骰子只能拿一个体积为1到6的物品
Last updated
Was this helpful?