背包算法轻松搞定——01背包算法、部分背包算法

这篇文章过程讲得很详细,一文搞懂(点击看原文)

不懂之前觉得很难理解,觉得很复杂,其实没有必要。因为只要懂动态规划就可以很轻松搞定0-1背包算法(部分背包算法更简单,排序即可)。之前看了很多篇文章都觉得太难了,好复杂,其实只是每个人逻辑思维不一样,别人说的你不一定能理解,但是多看几篇文章,总有一片你能轻易理解(就像上面那篇,一看懂)。

进入正题,由于上面的文章讲得很详细了,建议大家都去看上面的文章,这篇文章主要是给大家打个预防针,不要觉得很复杂(至少我一开始就觉得很复杂,过程各种疑问),搞懂了才发现,简单到爆炸。以及后面给出优化的思路(原文没有写的)

 

首先搞懂什么是背包算法

背包算法可以理解为在解题的过程中,模拟一个背包(二维数组),来记录背包从小到大的过程中能装的最有价值的东西,并且大多数题目都是以装东西为题,所以大家叫背包算法也很合理

01-背包算法和部分背包算法

0-1背包算法就是一个物品要么拿或者不拿,就像音响、吉他这样的物品。部分背包算法则是每个物品可以拿一部分,不需要全部拿完,像装沙子(10kg,60)、装水(20kg,100)、装饼干(30kg,120),数量各不一样,价值各不一样,怎么拿才能拿价值最高呢?(肯定全部拿最贵的啊。。。)

所以两种算法,较为复杂的是0-1背包算法(动态规划),部分背包算法很简单:如上面的沙子、水、和饼干,1kg沙子价值6,1kg水价值5,1kg饼干价值4,所以当一个50kg的背包,最划算的拿法肯定是先拿沙子(最贵,能拿完就拿完),同理,拿完水,最后还剩20kg的容量,拿饼干。

部分背包算法,就跟上面一样,很简单

接下来看一下0-1背包算法,动态规划的思想

采用从左到右(背包从1到最大容量),加上从上到下(可选择的物品从1个到n个)的双动态规划

具体的演示过程,上面文章写的很详细,我就不演示了。

对于一个物品(w=5,v=10),其在背包容量为n的时候,他有两者选择,拿这个物品,不拿这个物品

拿,    则价值=该物品价值v+背包容量【当前容量n-物品容量w】能装的最大价值  (动态规划,而不需要去重新排列组合计算)

不拿,则价值=背包容量【n】能装的最大价值(除了自己)。(也是动态规划,从上到下(物品从1件到n件))

所以比较拿与不拿就可以得出该容量的背包,该物品该不该拿

如果没看懂,可以去看原文的图解过程,真的和容易理解

这篇文章就是想大概给大家个方向,然后大家去看详细的图解过程绝对可以一看就懂

时间复杂度O(n*c) 空间复杂度O(n*c)

n为物品种类,c为规定的背包大小

优化思路

从图解可以看出,二维数组其实只会用到上一行的数据,即当行数为3时,只会通过第二行的数据来动态规划即可

所以n行的二位数组可以改成2行(一行记录上一行,一行记录当前行,需要多花n*c次遍历的时间,时间换空间的取舍)

递归思想

图解的过程是从上到下,从左到右,递归则可以相反,从最右边和最下边开始递归

即直接计算需要的答案   result=array[n][c]

计算array[n][c]的时候需要递归的去计算array[n-1][c]和array[n-1][c-w]+v的值做比较

通过这样逆序的去计算,最终也能得到结果,时间复杂度也是O(n*c),空间复杂度可以为O(1)

以上纯属个人总结,如果不对请指出,谢谢,更详细的题解可以看原文,图解过程很详细了

 

 

 

 

 

你可能感兴趣的:(技术积累)