洛谷 P1049 装箱问题
作者:互联网
嗯...
这道装箱问题其实就是一道典型的动态规划题目(有的DL说它是01背包问题还不太贴切
但无论如何,它肯定 是一道动归题...
众所周知,动归题的难点在于推出动态转移方程....
好了,在看题之前先说这些,下面先看一下题...
题目描述
有一个箱子容量为VVV(正整数,0≤V≤200000 \le V \le 200000≤V≤20000),同时有nnn个物品(0<n≤300<n \le 300<n≤30,每个物品有一个体积(正整数)。
要求nnn个物品中,任取若干个装入箱内,使箱子的剩余空间为最小。
输入输出格式
输入格式:111个整数,表示箱子容量
111个整数,表示有nnn个物品
接下来nnn行,分别表示这nnn个物品的各自体积
输出格式:111个整数,表示箱子剩余空间。
输入输出样例
输入样例#1:24 6 8 3 12 7 9 7输出样例#1:
0
说明
NOIp2001普及组 第4题
到这里,我们便开始推这道题的动态转移方程,也为本题核心...
因为题目要求使箱子的剩余空间最小的情况,相当于求箱子容量减箱子剩余空间最大的情况。
所以说状态转移方程为:
f[j]=max(f[j],f[j-w[i]]+w[i]);//求最大情况,不断更新
当我们推出动态转移方程之后,这道题就很简单了,所以请看代码:
1 #include<cstdio> 2 #include<iostream> 3 4 using namespace std; 5 6 int a[40], f[20005]; 7 8 int main(){ 9 int v, n; 10 scanf("%d%d",&v, &n); 11 for(int i = 1; i <= n; i++){ 12 scanf("%d",&a[i]); 13 } 14 for(int i = 1; i <= n; i++){ 15 for(int j = v; j >= a[i]; j--){ 16 if(f[j] <= v)//如果这个箱子还没装满 17 f[j] = max(f[j], f[j-a[i]] + a[i]);//则将箱子容量减箱子剩余空间最大的情况进行更新 18 //将f[j]与 f[j-a[i]] + a[i]进行比较,f[j]即为没向里加之前的情况,f[j-a[i]] + a[i]即为向内加入后的情况 19 if(f[j] == v){//如果正好满了 20 printf("0"); 21 return 0; 22 } 23 } 24 } 25 printf("%d",v - f[v]);//f[v]一直储存的是最大的所占空间,用v减去它,即可得最小的剩余空间 26 return 0; 27 }
嗯...就是这个样,最主要的部分就是其中的动态转移方程.....
标签:nnn,方程,洛谷,箱子,int,样例,...,P1049,装箱 来源: https://www.cnblogs.com/New-ljx/p/10440682.html