码迷,mamicode.com
首页 > 其他好文 > 详细

01背包思想和优化

时间:2019-10-25 18:03:43      阅读:124      评论:0      收藏:0      [点我收藏+]

标签:mil   顺序   完美   入门   有用   01背包   info   解决   状态更新   

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,哪讲错了欢迎大家拍砖

 

01背包思想和优化

标签:mil   顺序   完美   入门   有用   01背包   info   解决   状态更新   

原文地址:https://www.cnblogs.com/kekekuli/p/11739109.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!