01背包思想和优化

♀尐吖头ヾ 提交于 2019-12-02 08:49:49

dp入门问题:01背包装下了我们的忧伤QWQ

  作为一枚乐于作死...呸,乐于学习的蒟蒻,当然要学会装包的

那么简单的描述一下01背包问题:

  小明有个bag,容量是m.小明面前有n个物品,每个物品有它的价值vi和它的体积wi,小明想知道用这个背包能装到的物品总价值最大是多少.

好,这就是一个最朴素的01背包问题,那么怎么解决呢.

稍加思索...dp嘛,从小问题解决到大问题.我们用一个数组dp[i][j]表示选第i件物品时容量为j可以得到的最大价值。

状态转移方程就出来啦:dp[i][j]=max(dp[i-1][j],dp[i-1][j-w[i]]+[v[i]]);

其实01背包过程就是选与不选第i件物品,dp[i-1][j]实则就是不选第i件物品,dp[i-1][j-w[i]]+v[i]就是选了第i件物品,既然我们选了,那就要减掉它的wi再加上它的价值vi。然后在两者之间选最优方案就完美解决了

总的来说:01背包就是靠着第i-1的状态更新第i的状态

上代码:

 

 

再次开启脑洞:我们发现更新第i件物品的时候只需要用到第i-1的状态,之前的状态都可以抛弃,这样我们就可以抛弃i这个维度,只用一个维度保存j,这样做的的话,代码就变成了这样

 

 

注意这必须是逆序遍历,至于为什么呢?上面已经说过,01背包就是靠着第i-1的状态更新第i的状态,如果顺序遍历的话,第i状态的数据会覆盖掉第i-1状态的某一些数据,而这些被覆盖的数据保不准还有用于更新接下来的第i状态的,我们是要i-1更新i状态的,如果原i-1已经被覆盖成第i状态了,那么接下来就是用i状态更新i状态,显然是不符合定义的,而逆序遍历可以保证后面的数据先被更新成第i状态,前面的数据还是第i-1状态,那么用前面的数据(i-1状态)就可以保证不会出错

 

ps:这里可能有点绕,或许会不好理解,本来博主想用张动图解释解释的,奈何博主不会做动图QWQ,哪讲错了欢迎大家拍砖

 

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!