当前位置:   article > 正文

01 背包 (二维 )_二维背包

二维背包

首先是我对背包问题的理解:

        有一个背包可以放下 n kg,有一些物品,价值和重量一一对应,问题是,需要怎样才能使背包中的价值最大?

        不同的规则对应不同的背包问题

        01背包:每一个物品只能被放入一次

        完全背包:每个物品的放入数量不限

二维

1.dp[ i ] [ j ] 数组的含义

        下标: i 表示  0 - i 的物品中可以任取   j 表示 背包的容量

        值:表示,此时背包中的最大值

2. 递推公式

        不放物品 i :dp[ i ] [ j ]  = dp[ i  - 1 ] [ j ]  (也就是,和上一层的值是一样的

        放物品 i : dp[ i ] [ j ] =  dp[ i  - 1 ] [ j  - weight[  i  ] ] + value[ i ] )

注意,这里将 最后写的时候 取二者的最大值

3. 初始化

        因为最后需要靠二维数组中 左边 和 上面 进行推导,所以需要初始化两个位置

        

 

  1. for (int i = 0; i < weight.size(); i++)
  2. {
  3. dp[i][0] = 0;
  4. }
  5. for (int j = 1; j <= bagweight; j++)
  6. {
  7. dp[0][j] = value[0];
  8. }

      

4. 遍历顺序

        两层for循环,先遍历物品再遍历背包  /   先遍历背包再遍历物品 都可以

        因为当前的值,是依靠左上  或者 上方的 值来的,和遍历顺序没有关系。

  1. vector<int> weight = { 1, 3, 4 };
  2. vector<int> value = { 15, 20, 30 };
  3. int bagweight = 4;
  4. // 定义dp数组
  5. vector<vector<int>> dp(weight.size(), vector<int>(bagweight + 1, 0));
  6. // 初始化
  7. for (int i = 0; i < weight.size(); i++)
  8. {
  9. dp[i][0] = 0;
  10. }
  11. for (int j = 1; j <= bagweight; j++)
  12. {
  13. dp[0][j] = value[0];
  14. }
  15. // 遍历 + 递推
  16. for (int i = 1; i < weight.size(); i++)
  17. {
  18. for (int j = 0; j <= bagweight; j++)
  19. {
  20. if (j < weight[i]) dp[i][j] = dp[i - 1][j];
  21. else dp[i][j] = max(dp[i][j] = dp[i - 1][j], dp[i - 1][j - weight[i]] + value[i]);
  22. }
  23. }
  24. // 打印验证
  25. cout << dp[weight.size() - 1][bagweight] << endl;

本文内容由网友自发贡献,转载请注明出处:【wpsshop博客】
推荐阅读
相关标签
  

闽ICP备14008679号