首页 > 代码库 > 【dp】装箱问题

【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 }

 

 

【dp】装箱问题