4 条题解

  • 15
    @ 2023-8-1 19:39:14

    这是一个经典的背包问题,采用动态规划的思路可以解决。

    首先定义一个一维数组dp,其中dp[i]表示容量为i的箱子剩余的最小空间。

    初始化dp数组为0,表示当没有选取任何物品时,箱子的剩余空间为箱子的容量。

    然后使用动态规划的思路逐个计算dp数组的值。

    对于第i个物品,从后往前遍历容量j,有两种情况:

    1. 不选取第i个物品,此时剩余空间与上一个物品的状态相同,即dp[j] = dp[j]。
    2. 选取第i个物品,此时剩余空间等于上一个物品放入容量为(j-体积)的箱子中的剩余空间,即dp[j] = dp[j - volumes[i - 1]] + volumes[i - 1]。

    最后,dp[V]就是箱子的剩余空间。

    例如,输入数据为:24,6,8,3,12,7,9,7

    初始化dp数组为[0, 0, 0, ..., 0],长度为25(V+1)

    对于第一个物品8,从后往前遍历容量j,当j >= 8时,有dp[j] = max(dp[j], dp[j - 8] + 8),即dp[8] = max(0, dp[0] + 8) = 8,dp[9] = max(0, dp[1] + 8) = 8,...,dp[24] = max(0, dp[16] + 8) = 16。

    对于第二个物品3,从后往前遍历容量j,当j >= 3时,有dp[j] = max(dp[j], dp[j - 3] + 3),即dp[3] = max(0, dp[0] + 3) = 3,dp[4] = max(0, dp[1] + 3) = 3,...,dp[24] = max(0, dp[21] + 3) = 21。

    依此类推,计算完所有物品后,得到dp数组为[0, 0, ..., 16, 18, 21, 21, 24, 24, ..., 24]。

    最后,箱子剩余的最小空间为V - dp[V] = 24 - 24 = 0。

    #include <iostream>
    #include <vector>
    using namespace std;
    
    int min_remaining_space(int V, int n, vector<int>& volumes) {
        vector<int> dp(V + 1, 0);
    
        for (int i = 1; i <= n; i++) {
            for (int j = V; j >= volumes[i - 1]; j--) {
                dp[j] = max(dp[j], dp[j - volumes[i - 1]] + volumes[i - 1]);
            }
        }
    
        return V - dp[V];
    }
    
    int main() {
        int V, n;
        cin >> V >> n;
        vector<int> volumes(n);
        for (int i = 0; i < n; i++) {
            cin >> volumes[i];
        }
    
        cout << min_remaining_space(V, n, volumes) << endl;
    
        return 0;
    }
    
    
    • 6
      @ 2023-9-23 10:46:37

      一道01背包问题

      #include <iostream>
      #include <cstring>
      using namespace std;
      int f[20005], v[35], n, V;
      int main()
      {
          ios::sync_with_stdio(false);
          cin.tie(0);
          cout.tie(0);
          cin >> V;
          cin >> n;
          for (int i = 1; i <= n; i++)
              cin >> v[i];
          f[0] = 1;
          for (int i = 1; i <= n; i++)
              for (int j = V; j >= v[i]; j--)
                  f[j] += f[j - v[i]];
          for (int i = V; i >= 0; i--)
          {
              if (f[i] != 0)
              {
                  cout << V - i;
                  break;
              }
          }
          return 0;
      }
      
      • 0
        @ 2023-8-1 19:06:11

        这一题要求剩余空间最小,那么可以把物品的体积看做价值,从而套用01背包模型。

        参考代码

        m - f[m]

        • -9
          @ 2023-9-30 15:06:17
          五号线君精品(吗?)题解
          代码
          #include <bits/stdc++.h>
          int f[20005], v[35], n, V;
          int main()
          {
              std::scanf("%d%d",&V,&n);
              for (int i = 1; i <= n; i++) std::scanf("%d",&v[i]);
              f[0] = 1;
              for (int i = 1; i <= n; i++)
                  for (int j = V; j >= v[i]; j--)
                      f[j] += f[j-v[i]];
              for (int i = V; i >= 0; i--)
                  if (f[i]!=0)
                  {
                      std::printf("%d",V-i);
                      break;
                  }
              return 0;
          }
          //                                                                                                             @hetao8554411 版权所有
          
          版权 版权归发布者所有,未经允许不得copy
          • 1

          信息

          ID
          366
          时间
          1000ms
          内存
          256MiB
          难度
          4
          标签
          递交数
          583
          已通过
          283
          上传者