mirror of
https://github.com/youngyangyang04/leetcode-master.git
synced 2025-07-06 23:28:29 +08:00
Update
This commit is contained in:
@ -59,11 +59,11 @@
|
||||
* 求职
|
||||
* [程序员的简历应该这么写!!(附简历模板)](https://mp.weixin.qq.com/s/nCTUzuRTBo1_R_xagVszsA)
|
||||
* [BAT级别技术面试流程和注意事项都在这里了](https://mp.weixin.qq.com/s/815qCyFGVIxwut9I_7PNFw)
|
||||
* [深圳原来有这么多互联网公司,你都知道么?](https://mp.weixin.qq.com/s/3VJHF2zNohBwDBxARFIn-Q)
|
||||
* [北京有这些互联网公司,你都知道么?]()
|
||||
* [北京有这些互联网公司,你都知道么?](https://mp.weixin.qq.com/s/BKrjK4myNB-FYbMqW9f3yw)
|
||||
* [上海有这些互联网公司,你都知道么?]()
|
||||
* [成都有这些互联网公司,你都知道么?](https://mp.weixin.qq.com/s/Y9Qg22WEsBngs8B-K8acqQ)
|
||||
* [深圳原来有这么多互联网公司,你都知道么?](https://mp.weixin.qq.com/s/3VJHF2zNohBwDBxARFIn-Q)
|
||||
* [广州有这些互联网公司,你都知道么?](https://mp.weixin.qq.com/s/Ir_hQP0clbnvHrWzDL-qXg)
|
||||
* [成都有这些互联网公司,你都知道么?](https://mp.weixin.qq.com/s/Y9Qg22WEsBngs8B-K8acqQ)
|
||||
|
||||
|
||||
* 算法性能分析
|
||||
@ -217,6 +217,7 @@
|
||||
* [贪心算法:根据身高重建队列](https://mp.weixin.qq.com/s/-2TgZVdOwS-DvtbjjDEbfw)
|
||||
* [本周小结!(贪心算法系列三)](https://mp.weixin.qq.com/s/JfeuK6KgmifscXdpEyIm-g)
|
||||
* [贪心算法:根据身高重建队列(续集)](https://mp.weixin.qq.com/s/K-pRN0lzR-iZhoi-1FgbSQ)
|
||||
* [贪心算法:用最少数量的箭引爆气球](https://mp.weixin.qq.com/s/HxVAJ6INMfNKiGwI88-RFw)
|
||||
|
||||
|
||||
* 动态规划
|
||||
|
@ -130,8 +130,6 @@ public:
|
||||
|
||||
所以使用vector(动态数组)来insert,是费时的,插入再拷贝的话,单纯一个插入的操作就是O(n^2)了,甚至可能拷贝好几次,就不止O(n^2)了。
|
||||
|
||||
对于本题,不用vector的话,如果有多少人就申请多大的固定数组来模拟插入操作也可以,这样就不会有扩充数组的情况,但是就要真的手动模拟插入的操作了,比较麻烦。
|
||||
|
||||
改成链表之后,C++代码如下:
|
||||
|
||||
```C++
|
||||
|
@ -44,6 +44,11 @@
|
||||
* 背包如何正好装满,说明找到了总和为 sum / 2 的子集。
|
||||
* 背包中每一个元素一定是不可重复放入。
|
||||
|
||||
**按照这四部在分析一波**
|
||||
* 确定dp数组以及下标的含义
|
||||
* 确定递推公式
|
||||
* dp数组如何初始化
|
||||
* 确定遍历顺序
|
||||
|
||||
定义里数组为dp[],dp[i] 表示 背包中放入体积为i的商品,最大价值为dp[i]。
|
||||
|
||||
|
@ -1,22 +1,70 @@
|
||||
<p align='center'>
|
||||
<img src="https://img-blog.csdnimg.cn/20201215214102642.png" width=400 >
|
||||
</p>
|
||||
<p align="center">
|
||||
<a href="https://github.com/youngyangyang04/leetcode-master"><img src="https://img.shields.io/badge/Github-leetcode--master-lightgrey" alt=""></a>
|
||||
<a href="https://img-blog.csdnimg.cn/20201115103410182.png"><img src="https://img.shields.io/badge/刷题-微信群-green" alt=""></a>
|
||||
<a href="https://img-blog.csdnimg.cn/20201210231711160.png"><img src="https://img.shields.io/badge/公众号-代码随想录-brightgreen" alt=""></a>
|
||||
<a href="https://space.bilibili.com/525438321"><img src="https://img.shields.io/badge/B站-代码随想录-orange" alt=""></a>
|
||||
<a href="https://www.zhihu.com/people/sun-xiu-yang-64"><img src="https://img.shields.io/badge/知乎-代码随想录-blue" alt=""></a>
|
||||
<a href="https://www.toutiao.com/c/user/60356270818/#mid=1633692776932365"><img src="https://img.shields.io/badge/头条-代码随想录-red" alt=""></a>
|
||||
</p>
|
||||
|
||||
|
||||
> 代码很简单,思路很高端
|
||||
|
||||
# 435. 无重叠区间
|
||||
|
||||
题目链接:https://leetcode-cn.com/problems/non-overlapping-intervals/
|
||||
|
||||
给定一个区间的集合,找到需要移除区间的最小数量,使剩余区间互不重叠。
|
||||
|
||||
注意:
|
||||
可以认为区间的终点总是大于它的起点。
|
||||
区间 [1,2] 和 [2,3] 的边界相互“接触”,但没有相互重叠。
|
||||
|
||||
示例 1:
|
||||
输入: [ [1,2], [2,3], [3,4], [1,3] ]
|
||||
输出: 1
|
||||
解释: 移除 [1,3] 后,剩下的区间没有重叠。
|
||||
|
||||
示例 2:
|
||||
输入: [ [1,2], [1,2], [1,2] ]
|
||||
输出: 2
|
||||
解释: 你需要移除两个 [1,2] 来使剩下的区间没有重叠。
|
||||
|
||||
示例 3:
|
||||
输入: [ [1,2], [2,3] ]
|
||||
输出: 0
|
||||
解释: 你不需要移除任何区间,因为它们已经是无重叠的了。
|
||||
|
||||
## 思路
|
||||
|
||||
这道题目如果真的去模拟去重复区间的行为,是非常麻烦的,还要有删除区间。
|
||||
|
||||
**相信很多同学看到这道题目都冥冥之中感觉要排序,但是究竟是按照右边界排序,还是按照左边界排序呢?**
|
||||
|
||||
按照右边界排序,从左向右遍历,右边界越小越好,因为右边界越小,留给下一个区间的空间就越大,所以可以从左向右遍历,优先选右边界小的。
|
||||
这其实是一个难点!
|
||||
|
||||
按照左边界排序,那么就是从右向左遍历,左边界数值越大越好(越靠右),这样就给前一个区间的空间就越大,所以可以从右向左遍历。
|
||||
按照右边界排序,就要从左向右遍历,因为右边界越小越好,只要右边界越小,留给下一个区间的空间就越大,所以从左向右遍历,优先选右边界小的。
|
||||
|
||||
如果按照左边界排序,还从左向右遍历的话,要处理各个区间右边界的各种情况,就比较复杂了,这其实也就不是贪心了。
|
||||
按照左边界排序,就要从右向左遍历,因为左边界数值越大越好(越靠右),这样就给前一个区间的空间就越大,所以可以从右向左遍历。
|
||||
|
||||
如果按照左边界排序,还从左向右遍历的话,要处理各个区间右边界的各种情况,就很复杂了。
|
||||
|
||||
一些同学做这道题目可能真的去模拟去重复区间的行为,这是比较麻烦的,还要去删除区间。
|
||||
|
||||
题目只是要求移除区间的个数,没有必要去真实的模拟删除区间!
|
||||
|
||||
**我来按照右边界排序,从左向右记录非交叉区间的个数。最后用区间总数减去非交叉区间的个数就是需要移除的区间个数了**。
|
||||
|
||||
此时问题就是要求非交叉区间的最大个数。
|
||||
|
||||
右边界排序之后,局部最优:优先选右边界小的区间,所以从左向右遍历,留给下一个区间的空间大一些,从而尽量避免交叉。全局最优:选取最多的非交叉区间。
|
||||
|
||||
局部最优推出全局最优,试试贪心!
|
||||
|
||||
这里记录非交叉区间的个数还是有技巧的,如图:
|
||||
|
||||
<img src='../pics/435.无重叠区间.png' width=600> </img></div>
|
||||

|
||||
|
||||
区间,1,2,3,4,5,6都按照右边界排好序。
|
||||
|
||||
@ -26,7 +74,7 @@
|
||||
|
||||
区间4结束之后,在找到区间6,所以一共记录非交叉区间的个数是三个。
|
||||
|
||||
总共区间个数为6,减去非交叉区间的个数(3),为3。移除区间的最小数量就是3。
|
||||
总共区间个数为6,减去非交叉区间的个数3。移除区间的最小数量就是3。
|
||||
|
||||
C++代码如下:
|
||||
|
||||
@ -41,7 +89,7 @@ public:
|
||||
if (intervals.size() == 0) return 0;
|
||||
sort(intervals.begin(), intervals.end(), cmp);
|
||||
int count = 1; // 记录非交叉区间的个数
|
||||
int end = intervals[0][1];
|
||||
int end = intervals[0][1]; // 记录区间分割点
|
||||
for (int i = 1; i < intervals.size(); i++) {
|
||||
if (end <= intervals[i][0]) {
|
||||
end = intervals[i][1];
|
||||
@ -52,6 +100,33 @@ public:
|
||||
}
|
||||
};
|
||||
```
|
||||
* 时间复杂度:O(nlogn) ,有一个快排
|
||||
* 空间复杂度:O(1)
|
||||
|
||||
大家此时会发现如此复杂的一个问题,代码实现却这么简单!
|
||||
|
||||
# 总结
|
||||
|
||||
本题我认为难度级别可以算是hard级别的!
|
||||
|
||||
总结如下难点:
|
||||
|
||||
* 难点一:一看题就有感觉需要排序,但究竟怎么排序,按左边界排还是右边界排。
|
||||
* 难点二:排完序之后如何遍历,如果没有分析好遍历顺序,那么排序就没有意义了。
|
||||
* 难点三:直接求重复的区间是复杂的,转而求最大非重复区间个数。
|
||||
* 难点四:求最大非重复区间个数时,需要一个分割点来做标记。
|
||||
|
||||
**这四个难点都不好想,但任何一个没想到位,这道题就解不了**。
|
||||
|
||||
一些录友可能看网上的题解代码很简单,照葫芦画瓢稀里糊涂的就过了,但是其题解可能并没有把问题难点讲清楚,然后自己再没有钻研的话,那么一道贪心经典区间问题就这么浪费掉了。
|
||||
|
||||
贪心就是这样,代码有时候很简单(不是指代码短,而是逻辑简单),但想法是真的难!
|
||||
|
||||
这和动态规划还不一样,动规的代码有个递推公式,可能就看不懂了,而贪心往往是直白的代码,但想法读不懂,哈哈。
|
||||
|
||||
**所以我把本题的难点也一一列出,帮大家不仅代码看的懂,想法也理解的透彻!**
|
||||
|
||||
循序渐进学算法,认准「代码随想录」就够了,值得介绍给身边的朋友同学们!
|
||||
|
||||
> 我是[程序员Carl](https://github.com/youngyangyang04),组队刷题可以找我,本文[leetcode刷题攻略](https://github.com/youngyangyang04/leetcode-master)已收录,更多[精彩算法文章](https://mp.weixin.qq.com/mp/appmsgalbum?__biz=MzUxNjY5NTYxNA==&action=getalbum&album_id=1485825793120387074&scene=173#wechat_redirect)尽在:[代码随想录](https://img-blog.csdnimg.cn/20200815195519696.png),期待你的关注!
|
||||
|
||||
|
@ -1,7 +1,44 @@
|
||||
|
||||
// 如何转化为01背包问题
|
||||
# 思路
|
||||
|
||||
尽量让石头分成重量相同的两堆,相撞之后剩下的石头最小,**这样就化解成01背包问题了**。
|
||||
|
||||
只不过物品的重量为store[i],物品的价值也为store[i]。
|
||||
|
||||
对应着01背包里的物品重量weight[i]和 物品价值value[i]。
|
||||
|
||||
接下来进行动规四步曲:
|
||||
|
||||
* 确定dp数组以及下标的含义
|
||||
|
||||
我习惯直接使用一维dp数组,如果习惯使用二维dp数组的同学可以看这篇:
|
||||
|
||||
dp[j]表示容量(这里说容量更形象,其实就是重量)为j的背包,最多可以背dp[j]这么重的石头。
|
||||
|
||||
* 确定递推公式
|
||||
|
||||
dp[j]有两个来源方向,一个是dp[j]自己,一个是dp[j - stones[i]]。
|
||||
|
||||
那么dp[j]就是取最大的:**dp[j] = max(dp[j], dp[j - stones[i]] + stones[i]);**
|
||||
|
||||
一些同学可能看到这dp[j - stones[i]] + stones[i]中 又有- stones[i] 又有+stones[i],看着有点晕乎。
|
||||
|
||||
还是要牢记dp[j]的含义,要知道dp[j - stones[i]]为 容量为j - stones[i]的背包最大所背重量。
|
||||
|
||||
* dp数组如何初始化
|
||||
|
||||
既然 dp[j]中的j表示容量,那么最大容量(重量)是多少呢,就是所有石头的重量和。
|
||||
|
||||
因为提示中给出1 <= stones.length <= 30,1 <= stones[i] <= 1000,所以最大重量就是30 * 1000
|
||||
|
||||
如何初始化呢,只要因为重量都不会是负数,所以dp[j]都初始化为0就可以了,这样在递归公式dp[j] = max(dp[j], dp[j - stones[i]] + stones[i]);中dp[j]才不会初始值所覆盖。
|
||||
|
||||
* 确定遍历顺序
|
||||
|
||||
for循环遍历石头的数量嵌套一个for循环遍历背包容量,且因为是01背包,每一个物品只使用一次,所以遍历背包容量的时候要倒序。
|
||||
|
||||
具体原因我在
|
||||
|
||||
尽量让石头分成,重量相同的两堆,这样就化解成 01背包问题了。
|
||||
|
||||
```
|
||||
class Solution {
|
||||
@ -12,13 +49,14 @@ public:
|
||||
for (int i = 0; i < stones.size(); i++) sum += stones[i];
|
||||
int target = sum / 2;
|
||||
for (int i = 0; i < stones.size(); i++) {
|
||||
for (int j = target; j >= 0; j--) {
|
||||
if (j - stones[i] >= 0) {
|
||||
dp[j] = max(dp[j], dp[j - stones[i]] + stones[i]);
|
||||
}
|
||||
for (int j = target; j >= stones[i]; j--) {
|
||||
dp[j] = max(dp[j], dp[j - stones[i]] + stones[i]);
|
||||
}
|
||||
}
|
||||
return sum - dp[target] - dp[target];
|
||||
}
|
||||
};
|
||||
```
|
||||
|
||||
* 时间复杂度:O(m * n) , m是石头总重量,n为石头块数
|
||||
* 空间复杂度:O(m)
|
||||
|
@ -1,62 +1,88 @@
|
||||
# 什么是动态规划
|
||||
|
||||
动态规划,英文:Dynamic Programming,简称DP,如果某一问题有很多重叠子问题,使用动态规划是最有效的。
|
||||
|
||||
所以动态规划中每一个状态一定是由上一个状态推导出来的,**这一点就区分于贪心**
|
||||
所以动态规划中每一个状态一定是由上一个状态推导出来的,**这一点就区分于贪心**,贪心是局部直接选最优的,
|
||||
|
||||
在[关于贪心算法,你该了解这些!](https://mp.weixin.qq.com/s/O935TaoHE9Eexwe_vSbRAg)中我举了一个背包问题的例子。
|
||||
|
||||
例如:有N件物品和一个最多能被重量为W 的背包。第i件物品的重量是weight[i],得到的价值是value[i] 。**每件物品只能用一次**,求解将哪些物品装入背包里物品价值总和最大。
|
||||
|
||||
动态规划中dp[j]是又dp[j-weight[i]]推导出来的。
|
||||
|
||||
但如果是贪心呢,dp[j]每次选一个最大的或者最小的就完事了。
|
||||
|
||||
所以贪心解决不了动态规划的问题,这也是最大的区别。
|
||||
|
||||
很多讲解动态规划的文章都会讲最优子结构啊和重叠子问题啊这些,这些东西都是教科书的上定义,晦涩难懂而且不实用。
|
||||
|
||||
大家只要知道,动规是由前一个状态推导出来的,而贪心是局部直接算最优的,就够用了。
|
||||
|
||||
对于上述提到的背包问题,后序会详细讲解。
|
||||
|
||||
|
||||
# 动态规划的解题步骤
|
||||
|
||||
题目的时候,很多同学会陷入一个误区,就是以为把状态转移公式背下来,照葫芦画瓢改改,就开始写代码,甚至把题目AC之后,都不太清楚dp[i]表示的是什么。
|
||||
|
||||
这就是一种朦胧的状态,然后就把题给过了,遇到稍稍难一点的,可能直接就不会了,然后看题解,然后继续照葫芦画瓢陷入这种恶性循环中。
|
||||
|
||||
关于状态转移公式,
|
||||
状态转移公式(递推公式)是很重要,但动规不仅仅只有递推公式。
|
||||
|
||||
对于动态规划问题,我将拆解为如下四步曲,这四步都搞清楚了,才能说把动态规划真的掌握了!
|
||||
**对于动态规划问题,我将拆解为如下四步曲,这四步都搞清楚了,才能说把动态规划真的掌握了!**
|
||||
|
||||
* 确定dp数组以及下标的含义
|
||||
* dp数组如何初始化
|
||||
* 确定递推公式
|
||||
* dp数组如何初始化
|
||||
* 确定遍历顺序
|
||||
|
||||
一些同学可能想为什么要先确定递推公式,然后在考虑初始化呢?
|
||||
|
||||
因为一些情况是递推公式决定了dp数组要输入初始化!
|
||||
|
||||
后面的讲解中我都是围绕着这四个点来经行讲解。
|
||||
|
||||
可能刷过动态规划题目的同学可能都知道递推公式的重要性,感觉确定了递推公式这道题目就解出来了。
|
||||
|
||||
其实 确定递推公式 仅仅是解题里的一步而且, dp数组的初始化 以及确定遍历顺序,都非常重要,
|
||||
其实 确定递推公式 仅仅是解题里的一步而且,dp数组以及下标的含义, dp数组的初始化 以及确定遍历顺序,都非常重要。
|
||||
|
||||
**很多同学搞不清楚dp数组应该如何初始化,或者遍历的顺序,以至于记下来公式,但写的程序怎么改都通过不了**。
|
||||
后序的讲解的大家就会发现其重要性。
|
||||
|
||||
# 动态规划如何debug
|
||||
很多同学甚至知道递推公式,但搞不清楚dp数组应该如何初始化,或者正确的遍历顺序,以至于记下来公式,但写的程序怎么改都通过不了。
|
||||
|
||||
# 动态规划应该如何debug
|
||||
|
||||
平时我自己写的时候也经常出问题,**找问题的最好方式就是把dp数组打印出来,看看究竟是不是按照自己思路推导的!**
|
||||
|
||||
一些同学对于dp的学习是上来就是俯视类型的,总是想一下子全盘接纳,一鼓作气写出代码,如果代码能通过万事大吉,通过不了的话就凭感觉改一改。
|
||||
|
||||
# 背包三讲
|
||||
这是一个很不好的习惯!
|
||||
|
||||
背包九讲其实看起来还是有点费劲的,而且都是伪代码理解起来吃力
|
||||
<img src='../pics/416.分割等和子集1.png' width=600> </img></div>
|
||||
**做动规的题目,写代码之前一定要把状态转移在dp数组的上具体情况模拟一遍,心中有数,确定最后推出的是想要的结果**。
|
||||
|
||||
然后在写代码,如果代码没通过就打印dp数组,看看是不是和自己推导的哪里不一样。
|
||||
|
||||
如果和自己模拟推导的一样,那么就是自己的递归公式有问题。
|
||||
|
||||
如果和自己模拟推导的不一样,那么就是代码实现细节有问题。
|
||||
|
||||
**这样才是一个完整的思考过程,而不是一旦代码出问题,就毫无头绪的东改改西改改,最后过不了,或者说是稀里糊涂的过了**。
|
||||
|
||||
我来举一个例子:一些同学可能代码通过不了,都会把代码抛到出来问:我这里代码都已经和题解一模一样的,为什么通过不了呢?
|
||||
|
||||
发出这样的问题之前,其实可以自己先思考这三个问题:
|
||||
|
||||
* 这道题目我推导状态转移公式了么?
|
||||
* 我打印dp数组的日志了么?
|
||||
* 打印出来了dp数组和我想的一样么?
|
||||
|
||||
**如果这灵魂三问自己都做到了,基本上这道题目也就解决了**,或者更清晰的知道自己究竟是哪一点不明白,是状态转移不明白,还是实现代码不知道该怎么写,还是不理解遍历dp数组的顺序。
|
||||
|
||||
然后在问问题,目的性就很强了,回答问题的同学也可以快速知道提问者的疑惑了。
|
||||
|
||||
# 动态规划可以解决哪一类问题
|
||||
|
||||
|
||||
|
||||
|
||||
# 完全背包
|
||||
|
||||
有N 种物品和一个容量为V 的背包,每种物品都有无限件可用。放入第i种 物品的耗费的空间是Ci ,得到的价值是Wi 。求解:将哪些物品装入背包,可使 这些物品的耗费的空间总和不超过背包容量,且价值总和最大。
|
||||
|
||||
这个问题非常类似于01背包问题,所不同的是每种物品有无限件
|
||||
|
||||
|
||||
首先想想为什么01背包中要按照v递减的次序来 循环。让v递减是为了保证第i次循环中的状态F [i, v]是由状态F [i − 1, v − Ci]递 推而来。换句话说,这正是为了保证每件物品只选一次,保证在考虑“选入 第i件物品”这件策略时,依据的是一个绝无已经选入第i件物品的子结果F [i − 1, v − Ci]。而现在完全背包的特点恰是每种物品可选无限件,所以在考虑“加 选一件第i种物品”这种策略时,却正需要一个可能已选入第i种物品的子结 果F [i, v − Ci],所以就可以并且必须采用v递增的顺序循环。这就是这个简单的
|
||||
程序为何成立的道理。
|
||||
|
||||
|
||||
值得一提的是,上面的伪代码中两层for循环的次序可以颠倒。这个结论有可能会带来算法时间常数上的优化。(可能说的就是组合或者排列了)
|
||||
|
||||
# 多重背包
|
||||
|
||||
有N种物品和一个容量为V 的背包。第i种物品最多有Mi件可用,每件耗费 的空间是Ci ,价值是Wi 。求解将哪些物品装入背包可使这些物品的耗费的空间 总和不超过背包容量,且价值总和最大。
|
||||
|
||||
这题目和完全背包问题很类似。基本的方程只需将完全背包问题的方程略 微一改即可。
|
||||
|
||||
|
||||
# 总结
|
||||
|
||||
后台回复:背包九讲 就可以获得pdf
|
||||
|
@ -1,6 +1,6 @@
|
||||
很多刚刚关注「代码随想录」的录友,表示想从头开始打卡学习。
|
||||
|
||||
**打卡方式**就是在文章留言区记录:第n天打卡+自己的总结。很多录友都正在从头开始打卡,看看留言就知道了,你并不孤独,哈哈。
|
||||
**打卡方式**就是在文章留言区记录:第n天打卡(或者第n次打卡)+自己的总结。很多录友都正在从头开始打卡,看看留言就知道了,你并不孤独,哈哈。
|
||||
|
||||
**以下是我整理的文章列表,每个系列都排好了顺序,文章顺序即刷题顺序,这是全网最详细的刷题顺序了,所以录友们挨个看就OK!**
|
||||
|
||||
@ -17,11 +17,13 @@
|
||||
|
||||
* 求职
|
||||
* [程序员的简历应该这么写!!(附简历模板)](https://mp.weixin.qq.com/s/nCTUzuRTBo1_R_xagVszsA)
|
||||
* [BAT级别技术面试流程和注意事项都在这里了](https://mp.weixin.qq.com/s/815qCyFGVIxwut9I_7PNFw)
|
||||
* [深圳原来有这么多互联网公司,你都知道么?](https://mp.weixin.qq.com/s/Yzrkim-5bY0Df66Ao-hoqA)
|
||||
* [北京有这些互联网公司,你都知道么?]()
|
||||
* [互联网大厂技术面试流程和注意事项](https://mp.weixin.qq.com/s/815qCyFGVIxwut9I_7PNFw)
|
||||
* [北京有这些互联网公司,你都知道么?](https://mp.weixin.qq.com/s/BKrjK4myNB-FYbMqW9f3yw)
|
||||
* [上海有这些互联网公司,你都知道么?]()
|
||||
* [成都有这些互联网公司,你都知道么?]()
|
||||
* [深圳有这些互联网公司,你都知道么?](https://mp.weixin.qq.com/s/3VJHF2zNohBwDBxARFIn-Q)
|
||||
* [广州有这些互联网公司,你都知道么?](https://mp.weixin.qq.com/s/Ir_hQP0clbnvHrWzDL-qXg)
|
||||
* [成都有这些互联网公司,你都知道么?](https://mp.weixin.qq.com/s/Y9Qg22WEsBngs8B-K8acqQ)
|
||||
|
||||
|
||||
* 算法性能分析
|
||||
* [关于时间复杂度,你不知道的都在这里!](https://mp.weixin.qq.com/s/LWBfehW1gMuEnXtQjJo-sw)
|
||||
@ -167,6 +169,14 @@
|
||||
* [贪心算法:K次取反后最大化的数组和](https://mp.weixin.qq.com/s/dMTzBBVllRm_Z0aaWvYazA)
|
||||
* [本周小结!(贪心算法系列二)](https://mp.weixin.qq.com/s/RiQri-4rP9abFmq_mlXNiQ)
|
||||
* [贪心算法:加油站](https://mp.weixin.qq.com/s/aDbiNuEZIhy6YKgQXvKELw)
|
||||
* [贪心算法:分发糖果](https://mp.weixin.qq.com/s/8MwlgFfvaNYmjGwjuMlETQ)
|
||||
* [贪心算法:柠檬水找零](https://mp.weixin.qq.com/s/0kT4P-hzY7H6Ae0kjQqnZg)
|
||||
* [贪心算法:根据身高重建队列](https://mp.weixin.qq.com/s/-2TgZVdOwS-DvtbjjDEbfw)
|
||||
* [本周小结!(贪心算法系列三)](https://mp.weixin.qq.com/s/JfeuK6KgmifscXdpEyIm-g)
|
||||
* [贪心算法:根据身高重建队列(续集)](https://mp.weixin.qq.com/s/K-pRN0lzR-iZhoi-1FgbSQ)
|
||||
* [贪心算法:用最少数量的箭引爆气球](https://mp.weixin.qq.com/s/HxVAJ6INMfNKiGwI88-RFw)
|
||||
|
||||
|
||||
|
||||
|
||||
(持续更新.....)
|
||||
|
@ -129,3 +129,6 @@ void test_1_wei_bag_problem() {
|
||||
}
|
||||
|
||||
```
|
||||
# 总结
|
||||
|
||||
我个人倾向于使用一维dp数组的写法,比较直观简洁,所以在后面背包问题的讲解中,我都直接使用一维dp数组来进行推导。
|
||||
|
33
problems/背包问题理论基础.md
Normal file
33
problems/背包问题理论基础.md
Normal file
@ -0,0 +1,33 @@
|
||||
|
||||
# 背包问题
|
||||
|
||||
背包九讲其实看起来还是有点费劲的,而且都是伪代码理解起来吃力
|
||||
|
||||
# 完全背包
|
||||
|
||||
有N件物品和一个最多能背重量为W的背包。第i件物品的重量是weight[i],得到的价值是value[i] 。**每件物品都有无限个(也就是可以放入背包多次)**,求解将哪些物品装入背包里物品价值总和最大。
|
||||
|
||||
|
||||
完全背包和01背包问题唯一不同的地方就是,每种物品有无限件。
|
||||
|
||||
**终点讲解两个for顺序的问题,完全背包就可以换顺序了,因为不需要从后向前遍历了**。
|
||||
|
||||
|
||||
程序为何成立的道理。
|
||||
|
||||
|
||||
值得一提的是,上面的伪代码中两层for循环的次序可以颠倒。这个结论有可能会带来算法时间常数上的优化。(可能说的就是组合或者排列了)
|
||||
|
||||
# 多重背包
|
||||
|
||||
有N种物品和一个容量为V 的背包。第i种物品最多有Mi件可用,每件耗费 的空间是Ci ,价值是Wi 。求解将哪些物品装入背包可使这些物品的耗费的空间 总和不超过背包容量,且价值总和最大。
|
||||
|
||||
这题目和完全背包问题很类似。基本的方程只需将完全背包问题的方程略 微一改即可。
|
||||
|
||||
# 总结
|
||||
|
||||
<img src='../pics/416.分割等和子集1.png' width=600> </img></div>
|
||||
|
||||
# 总结
|
||||
|
||||
后台回复:背包九讲 就可以获得pdf
|
Reference in New Issue
Block a user