您的位置:首页 > 其它

总结: 0-1背包问题  --> 动态规划d…

2016-05-19 23:15 501 查看
                                                           
  动态规划

(参照刘汝佳代码)

1.  
有n种物品,每种只有一个.第i种物品的体积是Vi , 重量为Wj , 选一些物品装到一个容量为C的背包,

     
使得背包里面的物品不超过总体积C的前提下重量尽可能的大.

      1<=n<=100,
1<=Vi<=C<=10000,1<=Wi<=10^6

解法1:

状态方程: d(i,j) = max( d(i+1,j) , d(i+1,j-v[i]) +
w[j] );   (i > n 时,d(i,j) =
0.)

                
d(i,j)表示 当前第i层,背包剩余容量为j时接下来的最大重量和.

代码: d[1][c]为结果

for(int i = n; i >= 1;
--i)
{
  
 for(int j = 0; j <= c;
++j)
  
 {
  
   
 d[i][j] = (i == n ? 0 : d[i+1][j]);
  
   
 if(j >= v[i])
  
   
 {
  
   
   
 if(d[i][j] <=
d[i+1][j-v[i]]+w[i])
  
   
   
   
 d[i][j] = d[i+1][j-v[i]]+w[i];
  
   
 }
  
 }
}

解法2: 相反的规划方向.

采用对称的状态. 设f(i,j)
表示把前i个物品装到容量为j的最大总重量.

状态方程: f(i,j) = max( f(i-1,j) ,
f(i-1,j-v[i])+w[i] );

   
i == 0 时为0 ,  j < 0时负无穷.
结果为f(n,c);

代码:

for(int i =1 ; i <= n;
++i)
{
  
 for(int j = 0; j <= c;
++j)
  
 {
  
   
 f[i][j] = (i == 1 ? 0 : f[i-1][j]);
  
   
 if(j >= v[i])
  
   
 {
  
   
   
 if(f[i][j] <=
f[i-1][j-v[i]]+w[i])
  
   
   
   
 f[i][j] = f[i-1][j-v[i]]+w[i];
  
   
 }
  
 }
}

总结: 尽管在很多情况下,记忆化(剪枝)搜索程序直观,易懂. 但是计算顺序如果变得重要时

       
明显是递推时比较方便.效率相应高些. 同时规划的方向也是不唯一的看个人思维方向.
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: