P1016 装箱问题
时间: 1000ms / 空间: 131072KiB / Java类名: Main
背景
太原成成中学第2次模拟赛 第三道
描述
有一个箱子容量为v(正整数,o≤v≤20000),同时有n个物品(o≤n≤30),每个物品有一个体积 (正整数)。要求从 n 个物品中,任取若干个装入箱内,使箱子的剩余空间为最小。
输入格式
第一行,一个整数,表示箱子容量;
第二行,一个整数,表示有n个物品;
接下来n行,分别表示这n个物品的各自体积。
第二行,一个整数,表示有n个物品;
接下来n行,分别表示这n个物品的各自体积。
输出格式
一个整数,表示箱子剩余空间。
测试样例1
输入
24
6
8
3
12
7
9
7
输出
0
备注
Vivian Snow 提供!
DP 01背包问题。
对每个东西而言有0 1两种情况
f i表示能不能在i的空间得到i的价值
那么0一定可以
然后外部循环每一个东西
内部从剩余容量到1
循环枚举每一个剩余容量的情况
如果这个剩余容量可以
那么我带上这个ai也一定可以
所以第一个东西进去就是0+a1变成了1
第二个进去就是0+a2和0+a1+a2
第三个就是所有这些+a3可以
前提是加在一起不超过v
1 #include<iostream> 2 #include<cstring> 3 #include<cstdio> 4 #include<algorithm> 5 using namespace std; 6 int v,n; 7 int a[35]; 8 bool f[20005]; 9 int main() 10 { 11 scanf("%d%d",&v,&n); 12 for(int i=1;i<=n;i++) 13 scanf("%d",&a[i]); 14 f[0]=1; 15 for(int i=1;i<=n;i++) 16 for(int j=v-a[i];j>=0;j--) 17 if(f[j])f[j+a[i]]=1; 18 for(int i=v;i>=0;i--) 19 if(f[i]) 20 { 21 printf("%d",v-i); 22 puts(""); 23 break; 24 } 25 return 0; 26 }