Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit d4b4fd1

Browse files
committed
Update 01.Knapsack-Problem.md
1 parent e47975e commit d4b4fd1

File tree

1 file changed

+75
-4
lines changed

1 file changed

+75
-4
lines changed
Lines changed: 75 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,21 +1,92 @@
11
## 1. 背包问题简介
22

3-
> **背包问题**:背包问题是线性 DP 问题中一类经典而又特殊的模型。背包问题可以描述为:给定一组物品,每种物品都有自己的重量和价格,在限定的总重量内,我们如何选择,才能使得物品的总价格最高。
3+
### 1.1 背包问题的定义
4+
5+
> **背包问题**:背包问题是线性 DP 问题中一类经典而又特殊的模型。背包问题可以描述为:给定一组物品,每种物品都有自己的重量、价格以及数量。再给定一个最多能装重量为 $W$ 的背包。现在选择一些物品放入背包中,请问在总重量不超过背包装载重量上限的情况下,能装入背包的最大价值总合是多少?
6+
7+
根据物品限制条件的不同,背包问题可分为:0-1 背包问题、完全背包问题、多重背包问题、分组背包问题,以及混合背包问题等。
8+
9+
### 1.2 背包问题的暴力解题思路
10+
11+
背包问题的暴力解题思路比较简单。假设有 $n$ 件物品。我们先枚举出这 $n$ 件物品所有可能的组合。然后再对这些组合判断是否能放入背包,以及是否能得到最大价值。但是这种做法的时间复杂度是 $O(2^n),ドル其中 $n$ 表示物品数量。
12+
13+
暴力解法的时间复杂度是指数级别的,但是我们可以利用动态规划算法减少一下时间复杂度。
414

515
## 2. 0-1 背包问题
616

7-
> **0-1 背包问题**:有 $n$ 件物品和有一个最多能装重量为 $W$ 的背包。第 $i$ 件物品的重量为 $weight[i],ドル价值为 $value[i],ドル每件物品有且只有 1ドル$ 件。请问在总重量不超过背包重量上限的情况下,能装入背包的最大价值是多少?
17+
> **0-1 背包问题**:有 $n$ 件物品和有一个最多能装重量为 $W$ 的背包。第 $i$ 件物品的重量为 $weight[i],ドル价值为 $value[i],ドル每件物品有且只有 1ドル$ 件。请问在总重量不超过背包装载重量上限的情况下,能装入背包的最大价值是多少?
818
919
### 2.1 0-1 背包问题基本思路
1020

21+
> **0-1 背包问题的特点**:每种物品有且仅有 1ドル$ 件,可以选择放入背包,也可以选择不放入背包。
22+
23+
#### 思路 1:动态规划
24+
25+
###### 1. 划分阶段
26+
27+
按照物品的序号进行阶段划分。
28+
29+
###### 2. 定义状态
30+
31+
定义状态 $dp[i][w]$ 表示为:前 $i$ 件物品放入一个最多能装重量为 $w$ 的背包中,可以获得的最大价值。
32+
33+
状态 $dp[i][w]$ 是一个二维数组,其中第一维代表「当前正在考虑的物品」,第二维表示「当前背包的装载重量上限」,二维数组值表示「可以获得的最大价值」。
34+
35+
###### 3. 状态转移方程
36+
37+
对于「将前 $i$ 件物品放入一个最多能装重量为 $w$ 的背包中,可以获得的最大价值 」这个子问题,如果我们只考虑第 $i$ 件物品的放入策略(放入背包和不放入背包两种策略)。则问题可以转换为一个只跟前 $i - 1$ 件物品相关的问题。
38+
39+
1. **如果第 $i$ 件物品不放入背包**:问题转换为「前 $i - 1$ 件物品放入一个最多能装重量为 $w$ 的背包中 ,可以获得的最大价值为 $dp[i - 1][w]$」。
40+
2. **如果第 $i$ 件物品放入背包**:问题转换为「前 $i - 1$ 件物品放入一个最多能装重量为 $w - weight[i]$ 的背包中,可以获得的最大价值为 $dp[i - 1][w - weight[i]]$」」,再加上「放入的第 $i$ 件物品的价值 $value[i]$」,则此时可以获得的最大价值为 $dp[i - 1][w - weight[i]] + value[i]$。
41+
42+
当然第 $i$ 件物品能够放入背包的前提是:当前背包的装载重量上限 ≥ 第 $i$ 件物品的重量,即 $w \ge weight[i]$。
43+
44+
则状态转移方程为:
45+
46+
$dp[i][w] = max \begin{cases} dp[i - 1][w] & 第 i 件物品不放入背包 \cr dp[i - 1][w - weight[i]] + value[i] & 第 i 件物品放入背包 \end{cases}$
47+
48+
###### 4. 初始条件
49+
50+
- 如果背包容量为 0ドル,ドル则无论选取什么物品,可以获得的最大价值一定是 0ドル,ドル即 $dp[i][0] = 0$。
51+
- 前 0ドル$ 件物品所能获得的最大价值一定为 0ドル,ドル即 $dp[0][w] = 0$。
52+
53+
###### 5. 最终结果
54+
55+
#### 思路 1:代码
56+
57+
```Python
58+
class Solution:
59+
def zeroOnePack(self, weight: [int], value: [int], W: int):
60+
size = len(weight)
61+
dp = [[0 for _ in range(W + 1)] for _ in range(size + 1)]
62+
63+
for i in range(1, size + 1):
64+
for w in range(weight[i], W + 1):
65+
dp[i][w] = max(dp[i - 1][w], dp[i - 1][w - weight[i]] + value)
66+
67+
return dp[size]
68+
```
69+
70+
#### 思路 1:复杂度分析
71+
72+
- **时间复杂度**:$O(n \times W),ドル其中 $n$ 为物品数量,$W$ 为背包的装载重量上限。
73+
- **空间复杂度**:$O(n \times W)$。
74+
75+
### 2.2 0-1 背包问题滚动数组优化
76+
77+
78+
1179
## 3. 完全背包问题
1280

13-
> **完全背包问题**:有 $n$ 种物品和一个最多能装重量为 $W$ 的背包,第 $i$ 件物品的重量为 $weight[i],ドル价值为 $value[i],ドル每种物品数量没有限制。请问在总重量不超过背包重量上限的情况下,能装入背包的最大价值是多少?
81+
> **完全背包问题**:有 $n$ 种物品和一个最多能装重量为 $W$ 的背包,第 $i$ 件物品的重量为 $weight[i],ドル价值为 $value[i],ドル每种物品数量没有限制。请问在总重量不超过背包装载重量上限的情况下,能装入背包的最大价值是多少?
1482
1583
## 4. 多重背包问题
1684

17-
> **多重背包问题**:有 $n$ 种物品和一个最多能装重量为 $W$ 的背包,第 $i$ 种物品的重量为 $weight[i],ドル价值为 $value[i],ドル件数为 $count[i]$。请问在总重量不超过背包重量上限的情况下,能装入背包的最大价值是多少?
85+
> **多重背包问题**:有 $n$ 种物品和一个最多能装重量为 $W$ 的背包,第 $i$ 种物品的重量为 $weight[i],ドル价值为 $value[i],ドル件数为 $count[i]$。请问在总重量不超过背包装载重量上限的情况下,能装入背包的最大价值是多少?
86+
87+
## 5. 分组背包问题
1888

1989
## 参考资料
2090

2191
- 【资料】[背包九讲 - 崔添翼](https://github.com/tianyicui/pack)
92+
- 【文章】[背包 DP - OI Wiki](https://oi-wiki.org/dp/knapsack/)

0 commit comments

Comments
(0)

AltStyle によって変換されたページ (->オリジナル) /