装箱问题

题目描述:

有一个箱子容量为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


思路:

这道题与我之前说的0-1背包问题很相似。

只要把物品的体积看成价值就可以了。

很自然想到需要遍历所有情况,从中取出一个最大的数值。

我们假设:

 d(i,v_left) 表示从集合 i 中选出一定量的物品,选完后剩余空间为v_left的某种最优选择的最大值---在这里,表示最大的体积。

则,我们有:

d(i,v_left) = d(i-1, v_left)   vi>v_left

d(i , v_left) = max{ d(i-1,v_left) , d(i-1,v_left - vi) + vi }     选择是否放入物品i。

max{}的{}左边表示的是  不取i , 右边表示的是取 i , 至于为什么都是 i -1 ,(回顾我对d(i,v_left) 的定义读者自己思索。

依据这个原理,我们这次使用二维数组来表示,尽管会开比较大的空间。

代码如下:

#include <iostream>


using namespace std;


int d[31][20010]; //全局变量自动初始化为0


int max(int a,int b){
return a>b?a:b;
}


int box(int v[],int n,int V){
for(int i=1;i<=n;i++){
for(int w=0;w<=V;w++){
if(v[i]>w){
d[i][w]=d[i-1][w];
}
else{
d[i][w]=max(d[i-1][w],d[i][w-v[i]]+v[i]);
}
}
}
return d[n][V];
}


int main(){
int maxv;
int things;
cin>>maxv>>things;
int *v=new int[things+1];//从1开始表示数组下标
for(int i=1;i<=things;i++){
cin>>v[i];
}
cout<<maxv-box(v,things,maxv);
delete[] v; //释放内存
v=NULL; //指针悬空
}

总结:

对于N件物品,每件物品取一次,上限为M的动态规划

一般来说,解决该问题的函数是这样组成的:

1.一个数组,多少维视情况而定

2.两重循环:

第一重,从1--N;

第二重,从0--M;


不是绝对的。但初级的动态规划很多可以用这个思路来解决。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值