0-1背包问题的动态规划解法

问题描述:

         有n个物品,每个物品有对应的重量和价值。

编号

重量

价值

1

w[1]

v[1]

2

w[2]

v[1]

3

w[3]

v[3]

n

w[n]

v[n]

 

现在有一个可以承重m的背包(比较喜欢李宁的包)。求一组物品的组合(无重复),能使这组物品能全部放入包中(总重不超过m)而使包中物品总价值最大。

 

典型的动态规划题。用贪心算法是得不到最优解的。

 

问题分解:

         构建一个数组value[n+1][m+1],value[i][j]的意义是:前i个物品的组合去装入载重量为j的背包能达到的最大价值。

 

         我们先来把问题集中在这个数组上,关注这个迭代关系。

[cpp]  view plain copy
  1. for(i=1;i<row;i++)  
  2. {  
  3.          for(j=1;j<col;j++)  
  4.          {                  
  5.                    //前i-1个物品中的组合+物品i: 这一组合装入载重为j的包所能够达到的最大价值  
  6.                    inttemp = value[i-1][j-w[i]] + v[i];  
  7.    
  8.                    //w[i]<=j,且第i个物品装入背包后的价值>value[i-1][j],则更新当前最大价值  
  9.                    //否则第i个物品不装入背包  
  10.                    if(w[i]<=j&& temp>value[i-1][j])  
  11.                             value[i][j]=temp;  
  12.                    else  
  13.                             value[i][j]= value[i-1][j];  
  14.          }  
  15. }  


         当上面这个数组的内容全部确定之后,很明显value[n][m]是最大的价值量。那么这个物品组合是什么呢?可以逆推回来,如果value[n][m]>value[n-1][m],则第n个物品肯定是被装入背包的,且前n-1个物品被装入载重量为m-w[n]的背包中。我们设一个c[n+1],若物品i要被放入背包中则c[i]=1,否则c[i]=0。

[cpp]  view plain copy
  1. for(i = n,j = m;i > 0;i--)  
  2. {  
  3.          if(value[i][j]>value[i-1][j])  
  4.          {  
  5.                    c[i]=1;  
  6.                    j= j - w[i];  
  7.          }  
  8. }  


         解决了上面上个问题后,该问题已经解出了。只需要在循环前做好初始化工作,令value数组的值全为零。

  

         本博文介绍的问题中,每个物品只可以选一次,选中状态只会是0-1,因此称为是0-1背包问题。如果物品的选中次数是可以大于1且有具体限定的,则是有限背包问题;如果物品的选中次数是无限制的,则是无限背包问题。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值