【dp】装箱问题

装箱问题

                        (pack.pas/c/cpp)

                     来源:NOIP2001(普及组) 第四题

【问题描述】

有一个箱子容量为V(正整数,0<=V<=20000),同时有n个物品(0<n<=30=,每个物品有一个体积(正整数)。

要求n个物品中,任取若干个装入箱内,使箱子的剩余空间为最小。

 

【输入文件】

    第一 行一个正整数V表示箱子的容量,第二行一个正整数N表示物品个数,接下来N行列出这N个物品各自的体积。

【输出文件】

    单独一行,表示箱子最小的剩余空间。

【输入样例】

24

6

8

3

12

7

9

7

【输出样例】

    0

【问题分析】

本题是经典的0/1背包问题,并且是0/1背包的简化版,把箱子看做背包,容量看做载重量,体积看做重量,剩余空间最小也就是尽量装满背包。于是这个问题便成了:

有一个栽重量为V的背包,有N个物品,尽量多装物品,使背包尽量的重。

设计一个状态opt[i]表示重量i可否构成。

状态转移方程:opt[j]:=opt[j-w[1]]  {opt[j-w[i]]=true}

最终的解就是v-x(x<=n 且opt[x]=true 且 opt[x+1..n]=false)。


用01背包做


 1 #include<iostream>
 2 #include<algorithm>
 3 #include<string>
 4 #include<vector>
 5 #include<set>
 6 #include<queue>
 7 #include<map>
 8 #include<stack>
 9 #include<iterator>
10 #include<cstdio>
11 #include<cstring>
12 #include<cstdlib>
13 #include<cmath>
14 using namespace std;
15 typedef long long ll;
16 typedef unsigned long long ull;
17 #define clr(c) memset(c, 0, sizeof(c));
18 #define pi acos(-1.0)
19 const int INF = 0x3f3f3f3f;
20 const int mod = 1e9 + 7;
21 const double eps = 1e-8;
22 typedef struct point{
23     int x, y;
24     bool operator < (const point& p) const{
25         if (x == p.x) return y < p.y;
26         else return x < p.x;
27     }
28     bool operator >(const point& p) const{
29         return p < *this;
30     }
31 }p;
32 int a[1005];
33 int dp[1005];
34 int v, n;
35 
36 int main(){
37     while(~scanf("%d", &v)){
38         scanf("%d", &n);
39         for(int i = 0; i < n; i++) scanf("%d", &a[i]);
40         memset(dp, 0, sizeof(dp));
41         for(int i = 0; i < n; i++){
42             for(int j = v; j >= a[i]; j--){
43                 dp[j] = max(dp[j], dp[j-a[i]]+a[i]);
44             }
45         }
46         printf("%d\n", v-dp[v]);
47     }
48 
49     return 0;
50 }

 

 

posted @ 2016-10-05 17:12  快扶哀家去刷题  阅读(518)  评论(0编辑  收藏  举报