Always keep a begi|

Tobaa

园龄:1年1个月粉丝:1关注:1

01背包的推导

前言:太好了是动规我们没救了。

1.推导

背包容量为7,总共有四件物品,价值和重量表示为{v,w},它们的价值和重量分别是1{2,3},2{5,5},3{1,1},4{9,3},求背包最多能装多少

开始推导:

i表示装前i个物品,背包容量为j。

dp[1][1]=0,显然是0,因为物品1的重量为3,你装答辩啊。
dp[1][2]=0,容量不够还是不行。
dp[1][3]=2,背包的容量刚好装的下物品1,获得该物品的价值2。
......
dp[1][7]=2,为什么省略?因为就装一个物品1,再怎么装还是2。


dp[2][1]=0,容量是1你装史呢。
dp[2][2]=0,装不了,因为他善。
dp[2][3]=2,能装物品1,但物品2还是塞不进去。
........为什么省略,因为容量小于5且只装前2个就只能塞个物品1进去。
dp[2][5]=5,此时有两个选择,两个物品肯定是塞不进去的,装物品1还是物品2?显然是物品2,因为它的价值更大。
dp[2][6]=5,dp[2][7]=5,容量小,无法同时装下前两个物品。


dp[3][1]=1,能装物品3。
dp[3][2]=1
dp[3][3]=?1?2?=2,可以装前三个,多了一个物品三,物品2装不下,只能在物品1和物品3选,显然装价值大的。
dp[3][4]=3,装物品1和物品3
dp[3][5]=5,选其中价值最大的,max(v[1],v[2],v[3],v[1]+v[3])=5,
dp[3][6]=6,此时面临多种选择,可行的方案归纳为max(v[1],v[2],v[3],v[1]+v[3],v[2]+v[3])=max(2,5,1,3,6)=6。
dp[3][7]=6,同理。


dp[4][1]=0,dp[4][2]=0
dp[4][3]=9,显然是9,它比前面任何一个都大。
......
dp[4][4]=10,物品3和物品4。
.................同理
dp[4][7]=12,物品1+物品2+物品3。、
由此答案可得为12。


慢慢推太慢了,要发现其中的规律,观察dp[1][1]=0,dp[2][1]还是0,或是dp[2][5]=5,dp[3][5]=5,发现后者等于前者,其实你可以发现它们装的东西(决策)是一样的,后者也许面临多种选择但它的前身任然是最佳的(你要记住dp的每一步都是当前情况最佳的,不会改变),这算是一种继承,于是可得 dp[i][j]=dp[i1][j],但如果面临多种选择,它的前辈也许不再是局部最优解,那他就要重新作出选择,并进行比较,如上面的dp[4][3],它的前辈是dp[3][3]=2,因为此时i=4,所以这是它正在尝试把重量为3的物品4放进包里,要把物品4放进去,包的容积就减去3,得到上一次当包得容积为3-3=0时的局部最优解,也就是dp[3][0]=0,此时再加上物品4的价值就是9,那么dp[4][3]的一种选择就是9,要选最大,所以dp[4][3]=max(2,9)=9,我们可以发现9就是由dp[i-1][j-w[4]]+v[4]得来的,由此可得动态转移方程 dp[i][j]=max(dp[i1][jw[i]]+v[i],dp[i1][j])

1.1.优化空间

一但背包容量和物品数量变多了,就很容易爆空间,如dp[300][200000],所以要优化。可以用一个一维数组来维护,由于一维数组会被覆盖掉,dp[i-1][j]的情况还好,直接就承接覆盖前的内容,刚好就是上一行的同个位置,但dp[i-1][j-w[i]]+v[i]的情况不仅要dp[i-1][j]的值,还要它之前的值,但它之前的值已经被覆盖了,所以不能从前往后推导,而是要倒着推,它不会覆盖掉前面数组的内容,也就是说它不会覆盖dp[j-w[i]]的值,从前往后推你会发现你会破坏上一行的值导致后面不能利用上一行(覆盖前)的值,其导致的结果是一个物品被多次利用。推导可得dp[jw[i]]=dp[i1][jw[i]],dp[j]=dp[i1][j]。也就是 dp[j]=max(dp[j],dp[jw[i]])

2.看完的是这个

image

本文作者:Tobaa

本文链接:https://www.cnblogs.com/TobyL/p/18676698

版权声明:本作品采用知识共享署名-非商业性使用-禁止演绎 2.5 中国大陆许可协议进行许可。

posted @   Tobaa  阅读(7)  评论(0编辑  收藏  举报
点击右上角即可分享
微信分享提示
评论
收藏
关注
推荐
深色
回顶
收起