Skip to content

Commit 48692ef

Browse files
Update
1 parent 617346a commit 48692ef

File tree

6 files changed

+140
-3
lines changed

6 files changed

+140
-3
lines changed

README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -74,6 +74,7 @@
7474

7575
* 编程语言
7676
* [C++面试&C++学习指南知识点整理](https://github.com/youngyangyang04/TechCPP)
77+
* [C++语言基础课](https://kamacoder.com/course.php?course_id=1)
7778

7879
* 项目
7980
* [基于跳表的轻量级KV存储引擎](https://github.com/youngyangyang04/Skiplist-CPP)

problems/周总结/20201107回溯周末总结.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@ for (int i = startIndex; i < candidates.size() && sum + candidates[i] <= target;
3131

3232
[回溯算法:求组合总和(二)](https://programmercarl.com/0039.组合总和.html)第一个树形结构没有画出startIndex的作用,**这里这里纠正一下,准确的树形结构如图所示:**
3333

34-
![39.组合总和](https://code-thinking-1253855093.file.myqcloud.com/pics/20201123202227835.png)
34+
![39.组合总和](https://code-thinking-1253855093.file.myqcloud.com/pics/20201223170730367.png)
3535

3636
## 周二
3737

problems/回溯总结.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -116,8 +116,8 @@ void backtracking(参数) {
116116
**注意以上我只是说求组合的情况,如果是排列问题,又是另一套分析的套路**
117117

118118
树形结构如下:
119+
![39.组合总和](https://code-thinking-1253855093.file.myqcloud.com/pics/20201223170730367.png)
119120

120-
![39.组合总和](https://code-thinking-1253855093.file.myqcloud.com/pics/20201118152521990.png)
121121

122122
最后还给出了本题的剪枝优化,如下:
123123

problems/背包理论基础01背包-1.md

Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,9 @@
88

99
# 动态规划:01背包理论基础
1010

11+
12+
本题力扣上没有原题,大家可以去[卡码网第46题](https://kamacoder.com/problem.php?id=1046)去练习,题意是一样的。
13+
1114
## 算法公开课
1215

1316
**[《代码随想录》算法视频公开课](https://programmercarl.com/other/gongkaike.html)[带你学透0-1背包问题!](https://www.bilibili.com/video/BV1cg411g7Y6/),相信结合视频再看本篇题解,更有助于大家对本题的理解**
@@ -261,6 +264,55 @@ int main() {
261264

262265
```
263266

267+
本题力扣上没有原题,大家可以去[卡码网第46题](https://kamacoder.com/problem.php?id=1046)去练习,题意是一样的,代码如下:
268+
269+
```CPP
270+
271+
//二维dp数组实现
272+
#include <bits/stdc++.h>
273+
using namespace std;
274+
275+
int n, bagweight;// bagweight代表行李箱空间
276+
void solve() {
277+
vector<int> weight(n, 0); // 存储每件物品所占空间
278+
vector<int> value(n, 0); // 存储每件物品价值
279+
for(int i = 0; i < n; ++i) {
280+
cin >> weight[i];
281+
}
282+
for(int j = 0; j < n; ++j) {
283+
cin >> value[j];
284+
}
285+
// dp数组, dp[i][j]代表行李箱空间为j的情况下,从下标为[0, i]的物品里面任意取,能达到的最大价值
286+
vector<vector<int>> dp(weight.size(), vector<int>(bagweight + 1, 0));
287+
288+
// 初始化, 因为需要用到dp[i - 1]的值
289+
// j < weight[0]已在上方被初始化为0
290+
// j >= weight[0]的值就初始化为value[0]
291+
for (int j = weight[0]; j <= bagweight; j++) {
292+
dp[0][j] = value[0];
293+
}
294+
295+
for(int i = 1; i < weight.size(); i++) { // 遍历科研物品
296+
for(int j = 0; j <= bagweight; j++) { // 遍历行李箱容量
297+
// 如果装不下这个物品,那么就继承dp[i - 1][j]的值
298+
if (j < weight[i]) dp[i][j] = dp[i - 1][j];
299+
// 如果能装下,就将值更新为 不装这个物品的最大值 和 装这个物品的最大值 中的 最大值
300+
// 装这个物品的最大值由容量为j - weight[i]的包任意放入序号为[0, i - 1]的最大值 + 该物品的价值构成
301+
else dp[i][j] = max(dp[i - 1][j], dp[i - 1][j - weight[i]] + value[i]);
302+
}
303+
}
304+
cout << dp[weight.size() - 1][bagweight] << endl;
305+
}
306+
307+
int main() {
308+
while(cin >> n >> bagweight) {
309+
solve();
310+
}
311+
return 0;
312+
}
313+
314+
```
315+
264316

265317
## 总结
266318

problems/背包理论基础01背包-2.md

Lines changed: 46 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,14 +6,14 @@
66

77
# 动态规划:01背包理论基础(滚动数组)
88

9+
本题力扣上没有原题,大家可以去[卡码网第46题](https://kamacoder.com/problem.php?id=1046)去练习
910

1011
## 算法公开课
1112

1213
**[《代码随想录》算法视频公开课](https://programmercarl.com/other/gongkaike.html)[带你学透0-1背包问题!(滚动数组)](https://www.bilibili.com/video/BV1BU4y177kY/),相信结合视频再看本篇题解,更有助于大家对本题的理解**
1314

1415
## 思路
1516

16-
1717
昨天[动态规划:关于01背包问题,你该了解这些!](https://programmercarl.com/背包理论基础01背包-1.html)中是用二维dp数组来讲解01背包。
1818

1919
今天我们就来说一说滚动数组,其实在前面的题目中我们已经用到过滚动数组了,就是把二维dp降为一维dp,一些录友当时还表示比较困惑。
@@ -159,6 +159,8 @@ dp[1] = dp[1 - weight[0]] + value[0] = 15
159159

160160

161161

162+
C++代码如下:
163+
162164
```CPP
163165
void test_1_wei_bag_problem() {
164166
vector<int> weight = {1, 3, 4};
@@ -181,6 +183,49 @@ int main() {
181183

182184
```
183185

186+
本题力扣上没有原题,大家可以去[卡码网第46题](https://kamacoder.com/problem.php?id=1046)去练习,题意是一样的,代码如下:
187+
188+
```CPP
189+
// 一维dp数组实现
190+
#include <iostream>
191+
#include <vector>
192+
using namespace std;
193+
194+
int main() {
195+
// 读取 M 和 N
196+
int M, N;
197+
cin >> M >> N;
198+
199+
vector<int> costs(M);
200+
vector<int> values(M);
201+
202+
for (int i = 0; i < M; i++) {
203+
cin >> costs[i];
204+
}
205+
for (int j = 0; j < M; j++) {
206+
cin >> values[j];
207+
}
208+
209+
// 创建一个动态规划数组dp,初始值为0
210+
vector<int> dp(N + 1, 0);
211+
212+
// 外层循环遍历每个类型的研究材料
213+
for (int i = 0; i < M; ++i) {
214+
// 内层循环从 N 空间逐渐减少到当前研究材料所占空间
215+
for (int j = N; j >= costs[i]; --j) {
216+
// 考虑当前研究材料选择和不选择的情况,选择最大值
217+
dp[j] = max(dp[j], dp[j - costs[i]] + values[i]);
218+
}
219+
}
220+
221+
// 输出dp[N],即在给定 N 行李空间可以携带的研究材料最大价值
222+
cout << dp[N] << endl;
223+
224+
return 0;
225+
}
226+
227+
```
228+
184229
可以看出,一维dp 的01背包,要比二维简洁的多! 初始化 和 遍历顺序相对简单了。
185230

186231
**所以我倾向于使用一维dp数组的写法,比较直观简洁,而且空间复杂度还降了一个数量级!**

problems/背包问题理论基础完全背包.md

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,8 @@
77

88
# 动态规划:完全背包理论基础
99

10+
本题力扣上没有原题,大家可以去[卡码网第52题](https://kamacoder.com/problem.php?id=1046)去练习,题意是一样的。
11+
1012
## 算法公开课
1113

1214
**[《代码随想录》算法视频公开课](https://programmercarl.com/other/gongkaike.html)[带你学透完全背包问题! ](https://www.bilibili.com/video/BV1uK411o7c9/),相信结合视频再看本篇题解,更有助于大家对本题的理解**
@@ -162,6 +164,43 @@ int main() {
162164

163165
```
164166

167+
本题力扣上没有原题,大家可以去[卡码网第46题](https://kamacoder.com/problem.php?id=1046)去练习,题意是一样的,C++代码如下:
168+
169+
```cpp
170+
#include <iostream>
171+
#include <vector>
172+
using namespace std;
173+
174+
// 先遍历背包,再遍历物品
175+
void test_CompletePack(vector<int> weight, vector<int> value, int bagWeight) {
176+
177+
vector<int> dp(bagWeight + 1, 0);
178+
179+
for(int j = 0; j <= bagWeight; j++) { // 遍历背包容量
180+
for(int i = 0; i < weight.size(); i++) { // 遍历物品
181+
if (j - weight[i] >= 0) dp[j] = max(dp[j], dp[j - weight[i]] + value[i]);
182+
}
183+
}
184+
cout << dp[bagWeight] << endl;
185+
}
186+
int main() {
187+
int N, V;
188+
cin >> N >> V;
189+
vector<int> weight;
190+
vector<int> value;
191+
for (int i = 0; i < N; i++) {
192+
int w;
193+
int v;
194+
cin >> w >> v;
195+
weight.push_back(w);
196+
value.push_back(v);
197+
}
198+
test_CompletePack(weight, value, V);
199+
return 0;
200+
}
201+
```
202+
203+
165204
166205
## 总结
167206

0 commit comments

Comments
 (0)