(转)装箱问题


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