描述

已知一个背包最多能容纳体积之和为NC145 01背包 - 图2的物品,现有NC145 01背包 - 图3个物品,第NC145 01背包 - 图4个物品的体积为NC145 01背包 - 图5, 重量为NC145 01背包 - 图6,求当前背包最多能装多大重量的物品?

数据范围:

  • NC145 01背包 - 图7
  • NC145 01背包 - 图8
  • NC145 01背包 - 图9
  • NC145 01背包 - 图10

    进阶要求:时空复杂度NC145 01背包 - 图11

解决方法:动态规划

定义大小为n*V的二维数组dp,dp[i][j]表示在面对第i件物品且背包容量为j时,所能装入的最大重量 。

  • 如果j<v[i],背包容量不足以放下第i件物品,不能放入,dp[i][j]=dp[i-1][j];
  • 如果j>=v[i],背包容量足以放下第i件物品,那就有放和不放两种情况:

    • 如果放,那么dp[i][j]=dp[i-1][j-v[i]]+w[i],亦即前i-1件物品的最优重量+第i件物品的重量 ;
    • 如果不放,那么dp[i][j]=dp[i-1][j],亦即前i-1件物品在容量为j时的最优重量 ;
    • 具体放还是不放,就看哪种情况下价值最大了 。

      实现代码

      1. class Solution {
      2. public:
      3. /**
      4. * 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
      5. * 计算01背包问题的结果
      6. * @param V int整型 背包的体积
      7. * @param n int整型 物品的个数
      8. * @param vw int整型vector<vector<>> 第一维度为n,第二维度为2的二维数组,vw[i][0],vw[i][1]分别描述i+1个物品的vi,wi
      9. * @return int整型
      10. */
      11. int knapsack(int V, int n, vector<vector<int> >& vw) {
      12. // 全部初始化为0
      13. vector<vector<int> > dp(n+1, vector<int>(V+1, 0));
      14. for(int i=1; i<=n; i++){
      15. for(int j=1; j<=V; j++){
      16. if(j < vw[i-1][0]){
      17. // 背包容积不足
      18. dp[i][j] = dp[i-1][j];
      19. }
      20. else{
      21. // 背包容积够,可放可不放
      22. dp[i][j] = max(dp[i-1][j-vw[i-1][0]] + vw[i-1][1], dp[i-1][j]);
      23. }
      24. }
      25. }
      26. // 返回n件物品在容积为V时的最优重量即可
      27. return dp[n][V];
      28. }
      29. };

      运行效率评价

      运行时间:8ms,超过52.46% 用C++提交的代码;
      占用内存:4352KB,超过14.08%用C++提交的代码。