(轉)裝箱問題


Description

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

Input

每個測試文件只包含一組測試數據,每組輸入的第一行為一個整數V(0<=V<=20000),表示箱子的容量。
第二行輸入一個整數n(0<=n<=30),表示有n個物品。
接下來n行,每行輸入一個正整數,表示每個物品的體積。

Output

對於每組輸入數據,輸出一個整數,表示箱子剩余的最小空間。

Sample Input 1

24
6
8
3
12
7
9
7

Sample Output 1

0

Sample Input 2

 

90
12
3
7
4
5
13
2
8
4
7
6
5
7
Sample Output 2

19

解題思路:利用動態規划

我自己一開始的錯誤思想是用貪心算法,覺得先把最大的存進去,剩余的體積就是最小。題目提供的樣例都過了,但是提交的時候卻在某個樣例錯了。后來想了想才知道我這種想法有錯誤之處,先貼出我自己的錯誤代碼

 1 #include<iostream>
 2 #include<algorithm>
 3 using namespace std;
 4 
 5 int V,n;
 6 int a[40];
 7 int sum = 0;
 8 int main()
 9 {
10     cin>>V;
11     cin>>n;
12     for(int i = 0 ;i < n ;i++)
13     {
14         cin>>a[i];
15         sum += a[i];
16     }
17     if(sum<=V) cout<<V-sum;
18     else 
19     if(sum>V)
20     {
21         sort(a,a+n);
22         for(int i = n-1 ;i>=0;i--)
23         {
24             V -= a[i];
25             if(V<0)
26             {
27                 V += a[i];
28                 continue;
29             }
30         }
31         cout<<V;
32      } 
33      return 0;
34      
35 }

但是這種的話,后來想了一下,對於該數據正確答案是輸出0,但是上述代碼輸出了1;因為代碼先把99存進去了;

100
4
99 98 2 2

 

后來看了別人的博客,是利用動態規划

思路:

對於每一個物體,都有兩種選擇-放入或者不放入,所以外層循環可對每個物品進行遍歷,而每選擇一個物品,定會對大於該物品體積的dp數組元素產生影響,從而還需要一個內層數組對大於該物品體積的dp數組元素進行遍歷更新。更新方法為:dp[i] = max{ dp[i] , dp[i - vi]+vi },其中vi為當前物品的體積,max中的dp[i]表示不放入該物體時的解, dp[i - vi]+vi表示放入該物體時的解(i-vi表示給即將放入的物品留出合適的體積,如之前的例子,dp[i-vi]並不一定等於dp[i] - vi),取最大值,即為最優解。需要注意的是,需要先將dp數組中的每一個元素初始化為0。
對於如何運用 dp[i] = max{ dp[i] , dp[i - vi]+vi },下面舉個例子詳細說明一下過程。
原文:https://blog.csdn.net/elma_tww/article/details/86507716

 

 

繼續進行下去,直到遍歷完所有物品。

 

主要是思想,代碼其實挺簡單的,代碼如下:

 1 #include<iostream>
 2 #include<cmath>
 3 #include<string.h>
 4 using namespace std;
 5 
 6 
 7 int V,n;
 8 int a[40];
 9 int main()
10 {
11     cin>>V;
12     cin>>n;
13     int dp[V+1];
14     memset(dp,0,sizeof(dp)); 
15     for(int i = 0 ;i < n;i++)
16     {
17         cin>>a[i];
18         for(int j = V;j >= a[i];j--)
19         {
20             dp[j] = max(dp[j],dp[j-a[i]]+a[i]);
21         }
22     }
23     cout<<V-dp[V];
24     return 0;
25 }

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM