【藍橋杯】ALGO-21 裝箱問題

  • 2019 年 11 月 13 日
  • 筆記

版權聲明:本文為博主原創文章,遵循 CC 4.0 BY-SA 版權協議,轉載請附上原文出處鏈接和本聲明。

本文鏈接:https://blog.csdn.net/weixin_42449444/article/details/102985133

題目描述:

有一個箱子容量為V(正整數,0<=V<=20000),同時有n個物品(0<n<=30),每個物品有一個體積(正整數)。 要求n個物品中,任取若干個裝入箱內,使箱子的剩餘空間為最小。

輸入描述:

第一行為一個整數,表示箱子容量;第二行為一個整數,表示有n個物品。接下來n行,每行一個整數表示這n個物品的各自體積。

輸出描述:

一個整數,表示箱子剩餘空間。

輸入樣例:

24  6  8  3  12  7  9  7 

輸出樣例:

0

解題思路:

01背包問題。要使剩餘空間最小,則需要讓物品佔用背包的體積最大。dp[i][j]表示前i件物品放入體積為j的背包後所佔用的最大體積。將物品放入背包時需要考慮倆種情況:①若要放入的物品體積大於背包容量則不考慮放入背包;②若要放入的物品體積小於背包容量則考慮放入背包或者不放入背包,取佔用體積較大的那種情況。dp[n][v]就是將n件物品放入體積為v的背包後所佔用的最大體積,用v-dp[n][v]就是最後的輸出結果。

AC代碼:

#include <bits/stdc++.h>  using namespace std;  #define Up(i,a,b) for(int i = a; i <= b; i++)  const int maxv = 20001;  const int maxn = 31;    int dp[maxn][maxv];    //dp[i][j]表示前i件物品放入體積為j的背包後的最大體積    int main()  {      ios::sync_with_stdio(false);      cin.tie(0),cout.tie(0);      int v,n;    //箱子容量v,物品數n      cin >> v >> n;      Up(i,1,n)      {          int _;          cin >> _;          Up(j,1,v)          {              if(_ > j)   //當前物品體積大於背包容量就不放入背包              {                  dp[i][j] = dp[i-1][j];              }              else    //當前物品體積小於背包容量,考慮放入還是不放入背包              {                  dp[i][j] = max(dp[i-1][j],dp[i-1][j-_]+_);              }          }      }      cout << v-dp[n][v] << endl;      return 0;  }