|
47 | 47 |
|
48 | 48 | 那么只要找到集合里能够出现 sum / 2 的子集总和,就算是可以分割成两个相同元素和子集了。 |
49 | 49 |
|
50 | | -本题是可以用回溯暴力搜索出所有答案的,但最后超时了,也不想再优化了,放弃回溯,直接上01背包吧。 |
| 50 | +本题是可以用回溯暴力搜索出所有答案的,但最后超时了,也不想再优化了,放弃回溯。 |
| 51 | + |
| 52 | +是否有其他解法可以解决此题。 |
| 53 | + |
| 54 | +本题的本质是,能否把容量为 sum / 2的背包装满。 |
| 55 | + |
| 56 | +**这是 背包算法可以解决的经典类型题目**。 |
51 | 57 |
|
52 | 58 | 如果对01背包不够了解,建议仔细看完如下两篇: |
53 | 59 |
|
|
56 | 62 |
|
57 | 63 | ### 01背包问题 |
58 | 64 |
|
59 | | -背包问题,大家都知道,有N件物品和一个最多能背重量为W 的背包。第i件物品的重量是weight[i],得到的价值是value[i] 。每件物品只能用一次,求解将哪些物品装入背包里物品价值总和最大。 |
| 65 | +01背包问题,大家都知道,有N件物品和一个最多能背重量为W 的背包。第i件物品的重量是weight[i],得到的价值是value[i] 。每件物品只能用一次,求解将哪些物品装入背包里物品价值总和最大。 |
60 | 66 |
|
61 | 67 | **背包问题有多种背包方式,常见的有:01背包、完全背包、多重背包、分组背包和混合背包等等。** |
62 | 68 |
|
63 | 69 | 要注意题目描述中商品是不是可以重复放入。 |
64 | 70 |
|
65 | 71 | **即一个商品如果可以重复多次放入是完全背包,而只能放入一次是01背包,写法还是不一样的。** |
66 | 72 |
|
67 | | -**要明确本题中我们要使用的是01背包,因为元素我们只能用一次。** |
| 73 | +**元素我们只能用一次,如果使用背包,那么也是01背包** |
68 | 74 |
|
69 | 75 | 回归主题:首先,本题要求集合里能否出现总和为 sum / 2 的子集。 |
70 | 76 |
|
71 | | -那么来一一对应一下本题,看看背包问题如何来解决。 |
| 77 | +既有一个 只能装重量为 sum / 2 的背包,商品为数字,这些数字能不能把 这个背包装满。 |
72 | 78 |
|
73 | | -**只有确定了如下四点,才能把01背包问题套到本题上来。** |
| 79 | +那每一件商品是数字的话,对应的重量 和 价值是多少呢? |
74 | 80 |
|
75 | | -* 背包的体积为sum / 2 |
76 | | -* 背包要放入的商品(集合里的元素)重量为 元素的数值,价值也为元素的数值 |
77 | | -* 背包如果正好装满,说明找到了总和为 sum / 2 的子集。 |
78 | | -* 背包中每一个元素是不可重复放入。 |
| 81 | +一个数字只有一个维度,即 重量等于价值。 |
79 | 82 |
|
80 | | -以上分析完,我们就可以套用01背包,来解决这个问题了。 |
| 83 | +当数字 可以装满 承载重量为 sum / 2 的背包的背包时,这个背包的价值也是 sum / 2。 |
81 | 84 |
|
82 | | -动规五部曲分析如下: |
| 85 | +那么这道题就是 装满 承载重量为 sum / 2 的背包,价值最大是多少? |
83 | 86 |
|
84 | | -1. 确定dp数组以及下标的含义 |
| 87 | +如果最大价值是 sum / 2,说明正好被商品装满了。 |
85 | 88 |
|
86 | | -01背包中,dp[j] 表示: 容量为j的背包,所背的物品价值最大可以为dp[j]。 |
| 89 | +因为商品是数字,重量和对应的价值是相同的。 |
87 | 90 |
|
88 | | -本题中每一个元素的数值既是重量,也是价值。 |
| 91 | +以上分析完,我们就可以直接用01背包 来解决这个问题了。 |
89 | 92 |
|
90 | | -**套到本题,dp[j]表示 背包总容量(所能装的总重量)是j,放进物品后,背的最大重量为dp[j]**。 |
| 93 | +动规五部曲分析如下: |
| 94 | + |
| 95 | +1. 确定dp数组以及下标的含义 |
91 | 96 |
|
92 | | -那么如果背包容量为target, dp[target]就是装满 背包之后的重量,所以 当 dp[target] == target 的时候,背包就装满了。 |
| 97 | +01背包中,dp[j] 表示: 容量(所能装的重量)为j的背包,所背的物品价值最大可以为dp[j]。 |
| 98 | + |
| 99 | +如果背包所载重量为target, dp[target]就是装满 背包之后的总价值,因为 本题中每一个元素的数值既是重量,也是价值,所以,当 dp[target] == target 的时候,背包就装满了。 |
93 | 100 |
|
94 | 101 | 有录友可能想,那还有装不满的时候? |
95 | 102 |
|
@@ -192,12 +199,11 @@ public: |
192 | 199 |
|
193 | 200 | ## 总结 |
194 | 201 |
|
195 | | -这道题目就是一道01背包应用类的题目,需要我们拆解题目,然后套入01背包的场景。 |
| 202 | +这道题目就是一道01背包经典应用类的题目,需要我们拆解题目,然后才能发现可以使用01背包。 |
196 | 203 |
|
197 | 204 | 01背包相对于本题,主要要理解,题目中物品是nums[i],重量是nums[i],价值也是nums[i],背包体积是sum/2。 |
198 | 205 |
|
199 | | -看代码的话,就可以发现,基本就是按照01背包的写法来的。 |
200 | | - |
| 206 | +做完本题后,需要大家清晰:背包问题,不仅可以求 背包能被的最大价值,还可以求这个背包是否可以装满。 |
201 | 207 |
|
202 | 208 | ## 其他语言版本 |
203 | 209 |
|
|
0 commit comments