文章链接: 二维背包问题、 一维背包问题、 416. 分割等和子集
视频链接: 二维背包问题、 一维背包问题、 416. 分割等和子集
题目链接: 背包问题、 416. 分割等和子集
背包问题理论基础
背包问题分类:
01 背包(二维)
思路:
1.dp[i][j]数组的含义:任取[0, i]的物品放入容量为 j 的背包里的最大价值;
2.递推公式:①不放物品i:dp[i][j] = dp[i - 1][j]; ②放物品 i : dp[i][j] = dp[i - 1][j - weight[i]] + val[i];
综上,递推公式是 :dp[i][j] = max(dp[i - 1][j], dp[i - 1][j - weight[i]] + val[i]);
3.初始化数组:
dp[i][0],无论是选取哪些物品,背包价值总和一定为0。
dp[0][j],当 j < weight[0]的时候,dp[0][j] 应该是 0,因为背包容量比编号0的物品重量还小。
当j >= weight[0]时,dp[0][j] 应该是value[0],因为背包容量放足够放编号0物品。
01 背包(一维、滚动数组)
思路:
1.dp[i][j]数组的含义:dp[j]表示:容量为j的背包,所背的物品价值可以最大为dp[j]。
2.递推公式:dp[j] = max(dp[j], dp[j - weight[i]] + value[i]);
3.初始化数组:下标为0的值为0;而对于下标不为0的值,为了让dp数组在递归公式的过程中取的最大的价值,而不被初始值覆盖,只需要将其初始值也设置为0就行了。
注意:
两个循环不能交换顺序,为什么?
如果交换了顺序,就是一直循环第一个物品了。(可以自己模拟试试)
416.分割等和子集
思路:
如何将该问题抽象成01背包问题?
背包的容量就是数组和的一半;只要能找出一个数组的和等于这个背包的容量就是返回true,否则就是false。
该背包问题中的重量和价值分别是什么?
重量和价值都是所给数组的值,也就是说二者是等价的。这也进一步说明了dp[target] = target;就是true的判定条件。
1.dp[i]数组的含义:表示容量为i时,背包里的最大价值的值。
2.递推公式:dp[j] = max(dp[j], dp[j - nums[i]] + nums[i]);
3.初始化数组:都为0;