您的位置:首页 > 其它

codevs1014 装箱问题

2017-07-08 18:24 295 查看


1014 装箱问题

 

2001年NOIP全国联赛普及组

 时间限制: 1 s

 空间限制: 128000 KB

 题目等级 : 黄金 Gold



题解

4000

题目描述 Description

有一个箱子容量为V(正整数,0<=V<=20000),同时有n个物品(0<n<=30),每个物品有一个体积(正整数)。
要求n个物品中,任取若干个装入箱内,使箱子的剩余空间为最小。

输入描述 Input Description

一个整数v,表示箱子容量
一个整数n,表示有n个物品
接下来n个整数,分别表示这n 个物品的各自体积

输出描述 Output Description

一个整数,表示箱子剩余空间。

样例输入 Sample Input

24
6
8
3
12
7
9
7

样例输出 Sample Output

0

将前i件物品放入容量为v的背包中”这个子问题,若只考虑第i件物品的策略(放或不放),那么就可以转化为一个只牵扯前i-1件物品的问题。如果不放第i件物品,那么问题就转化为“前i-1件物品放入容量为v的背包中”,价值为dp[i-1][v];如果放第i件物品,那么问题就转化为“前i-1件物品放入剩下的容量为v-a[i]的背包中”,此时能获得的最大价值就是dp[i-1][v-a[i]]再加上通过放入第i件物品获得的价值a[i]。

/*************************************************************************
> File Name: 装箱问题.cpp
> Author: YinJianxiang
> Mail: YinJianxiang123@gmail.com
> Created Time: 2017年07月08日 星期六 18时21分01秒
************************************************************************/

#include <stdio.h>
#include <string.h>

#define max(a,b)(a>b?a:b)

int main(void) {
int v;
int n;
int i;
int j;
int a[31];
int dp[20001];

scanf("%d",&v);
scanf("%d",&n);
for(i = 1;i <= n;i++) {
scanf("%d",&a[i]);
}
memset(dp,0,sizeof(dp));
for(i = 1;i <= n;i++) {
for(j = v;j >= a[i];j--) {
dp[j] = max(dp[j],dp[j-a[i]] + a[i]);
}
}
printf("%d\n",v-dp[v]);

return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: