经典算法问题——“0” “1”背包问题

本文详细解析了01背包问题的两种算法实现过程,包括从上到下的输出方法和从下到上的输出方法。通过实例讲解了如何根据物品价值和容量,计算背包最大价值,并填充动态规划表格。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

对于“”0 “ 1”背包问题相信大家对于网上的问题一定找了很多,无非两种算法,即——

(1)方向为从上到下的进行输出的问题

 (2)方向为从下到上的一次输出的问题

 

V为所放入的物品的价值所在    W为所放入的物品的容量     

C设为背包的总容量

v1=1v2=3v3=5v4=9

w1=2

w2=3w3=4w4=7

 

如何根据给出的填充好下面的表格:

i/j012345678910
1           
2           
3           
4           

其中I对应的列为物品数目(我列举的例子中只放入了三个物品,所以对应的行有四行)

其中j对应的行为物品数目(我列举的例子中只放入了三个物品,所以对应的行有10列  )

PS:其中“0列”  只是为了补位用的 ,可根据需要进行相应的应用或者不用

 

具体的规则如下:    m(i,j)=  m(i+1,j)       j<w(i)     //不放入物品时候执行的方法

                                                 = Max【m(i+1,j);m(i+1,j-w(i))+v(i)】  j>w(i)     //放入物品时候的执行的方法

 

i/j

012345678910
1           
2           
3           
400000009999

对于执行方法 m(i,j)=m(i+1,j)时 此时需要注意的是,执行的顺序的从最下面进行相应的执行,一行一行的进行填充,第四个为最小的单元,为第一个放入包中的物品。

对于网上还有资料进行展示的是m(i,j)=m(i-1,j)时候此时需要注意的是,执行的顺序的从最上面进行相应的执行,即第一个物品为最小的单元,为第一个放入包中的物品。

同时!!!!!!需要注意的是 :每一行事实上只有放一个物品    一定要摆脱每一行可以放很多物品的错误想法

 

具体执行的方法:    1.考虑 j 的容量和物品的容量的w(i)大小关系     

           若w(i)>j  则物品不放入

          若w(i)<j  则物品有两种选择 :   

        (1)放入;则需要比较Max【m(i+1,j);m(i+1,j-w(i))+v(i)】取其中的最大值       

                v(i)为当前你需要放入背包的物品的价值

         (2) 不放入,则只需要在相应的位数计算m(i,j)=  m(i+1,j)的数值大小进行填充  

 

本题中对于第一行也就是第四个物品所对应的行来说;物品4的重量为7,即所需要的最小的j应该为7 所以对应的7前面的所有数值都为   “0”   ,因为背包的容量较小,而所放入的物品的容量过大,大于j的数值,所以为0   ,

同时对于背包容量为7的时候,正好满足w(4)的数值,所以能放入进背包,此时对应的价值为 9 ,填入表中,

对于基础行来讲,一旦物品放入了,则背包中就满足了4进入了背包,由于之前说到,要明确每一行只是填充一个物品,所以,对于 j==7 之后的背包的价值都为9,按顺序填充即可。

<!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!>

同理第二行,即数字三所对应的行来讲,一样的重复上述操作:

(1)首先看w(3)和j的关系找到最低的要求能放入的对应的“J”,不满足的补充为零,

i/j

012345678910
1           
2           
300005      
400000009999

 

(2)查询可知道w(3)=4 所以最低的需要的  “ j ”至少为 4   ,故4之前的都填充为 0 

(3)对于4之后的数字需要执行的是与基础行有所不同,此时背包容量满足能放入的条件

故:需要执行Max【m(i+1,j);m(i+1,j-w(i))+v(i)】取其中的最大值 来确定所需要填充的数值

m(3,4)=m(3+1,4)=0              m(3,4)=m(3+1,4-w(3))+v(3)=m(4,0)+5 = 5

    此时m(3,4)中所需要填充的数值为两者中的max数值,所以max=5  故m(3,4)=5

 

后面的数值则依次执行相应的操作即可   确定m(3,5)   依次填充完对应的“第二行”的数值即可          

i/j

012345678910
1           
2           
300005559999
400000009999

 

同理:对于倒数第三行来讲则执行与倒数第二行一样的操作即可

i/j

012345678910
1           
2000355599912
300005559999
400000009999

 

此方法中最后的原问题是最右上角的问题,最后的表格为如下图所示

i/j

012345678910
10013556991012
2000355599912
300005559999
400000009999

 

具体细节如上图所示(前提是执行的为m(i,j)=m(i+1,j))

 

二.备忘录

“0 1 背包问题中 ”填充的x(i)为是否放入的说明,只有两个默认的数值,一个为“ 0 ” 表示没放入背包

一个为“1”表示放入了背包,比较方法如下:     

若m(i,j) == m(i+1,j)数值相同说明没放入背包 ,填入备忘录的数值为   0

若m(i,j) != m(i+1,j)数值相同说明放入背包,填入备忘录的数值为   1

 

 

m(i,j)m(i+1,j)x(i)
m(3,7)m(4,7)0
m(1,6)m(2,6)1
   
   

上述表中数值只是为了说明如何进行填充的方法,具体顺序视题目而定

《《》《》《》《》《》《》《《》《》《》《》《》《》《》《》《》《》《》《》《》《》《》《》《》《》《》《》

最后呢:

补充!!!!!!!!!!!!!!!!

而对于网络上很多执行的m(i,j)=m(i-1,j)时候则基础行转为第一行所对应的数值即可,第一行的第一个物品为最小子元素,最右下角为原问题,其他操作与上述方法一样

 

如果对您有帮助的话请记得点一个关注哦,欢迎您的评论和支持,还在继续更新中。。。。。。

我是楠先生,谢谢您宝贵的意见

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值