-
前言
状态:前两题为背包基础题,直接看的题解。416 也是看的解析。 -
更新
1 | 24-06-20 初始记录 |
初步题解
416 分割等和子集
题目链接:(https://leetcode.cn/problems/partition-equal-subset-sum)
看解析
01 背包问题 二维
题目链接 + 解析:(https://programmercarl.com/背包理论基础01背包-1.html)
-
确定
dp[i][j]
的含义:从下标为[0-i]
的物品里任意取,放进容量为 j 的背包,价值总和最大是多少。 -
递推公式:
dp[i][j] = Math.max(dp[i - 1][j], dp[i - 1][j - weight[i]] + value[i])
(即,不存放当前物品/存放当前物品) -
dp 数组的初始化:
dp[i][0]
均为 0,dp[0][j]
需要根据实际情况来。 -
遍历顺序:从前向后遍历。
-
打印 dp 数组(用于 debug)
1 | public static void main(String[] args) { |
01 背包问题 一维
题目链接 + 解析:(https://programmercarl.com/背包理论基础01背包-2)
-
确定
dp[j]
的含义:从物品里任意取,放进容量为 j 的背包,价值总和最大是多少。 -
递推公式:
dp[j] = Math.max(dp[j], dp[j - weight[i]] + value[i])
(即,要么等于原值,要么等于放入物品的值) -
dp 数组的初始化:
dp[0] = 0
。 -
遍历顺序:从后向前遍历。(这里需要注意,因为递推公式内需要上一层的原值,只有倒序遍历,可以获取上一层的原值。)
-
打印 dp 数组(用于 debug)
1 | /** |
416 分割等和子集
解析:(https://programmercarl.com/0416.分割等和子集.html)
-
确定
dp[j]
的含义:从物品里任意取,求总量的最大值,判断是否等于j
即sum/2
。这题要抽象,设置 i 位置的重量和价值都为 i -
递推公式:
dp[j] = Math.max(dp[j], dp[j - weight[i]] + value[i])
(如果dp[j] == j
说明,集合中的子集总和正好可以凑成总和 j) -
dp 数组的初始化:因为是正整数数组,所以可以初始化为 0。
-
遍历顺序:从后向前遍历。
-
打印 dp 数组(用于 debug)
1 | public boolean canPartition(int[] nums) { |