11083 旅游背包

11083 旅游背包

时间限制:5000MS 内存限制:65535K

题型:编程题   语言:无限制

Description

想去旅游吗?那得先准备背包!

 

背包用来装旅游物品,现在共n种(n<=50)旅游物品,每种物品都有体积vi,重量wi,数量ci,价值ti(vi,wi,ci和ti都为整数)。

限制体积最多V立方厘米(V<=1000),重量最多W公斤(W<=500)。

 

请问你如何选择物品,使得带上的物品总价值最大,这个最大总价值为多少?

 

比如:

物品编号  体积(立方厘米)    重量(公斤)        数量(个)          价值(元)

1         30                  3                   10                  4

2         50                  8                   10                  5

3         10                  2                   10                  2

4         23                  5                   8                   3

5         130                 20                  5                   11

 

若V为500,W为100,则选择物品的最大价值为72(且72=10*4+10*2+4*3:由10件物品1,10件物品3,和4件物品4组成)。

 

这是一个多维且有界的背包问题,属于常规0-1背包问题的扩展问题。

 

Input

第一行,物品的种类n,背包体积的限制V,背包载重量的限制W。n,V和W的范围如前所述。

接下来n行,每行为该种物品i的体积vi,重量wi,数量ci,价值ti (规定vi,wi,ci和ti都为整数)。

Output

仅一行,为选择物品子集所能获得的最大价值。

Sample Input

5 500 100

30 3 10 4

50 8 10 5

10 2 10 2

23 5 8 3

130 20 5 11

Sample Output

72

Hint

此为多维有界的背包问题。

 

n种物品,每种物品体积v[i],重量w[i],c[i]件,价值t[i]。

设f[i][x][y]表示:可选前i种物品,选出物品体积和不超过x,重量和不超过y的最大价值。

由于f[i][x][y]是一个比较大的空间,请不要在函数内部定义,放到函数外做全局变量来定义才可。

则三维数组f先全部初始化为0,f[i][x][y]递归关系如下:

if i=1

f[1][x][y]= 0,                                if x/v[1]=0 ||y/w[1]=0

f[1][x][y]=min(x/v[1], y/w[1], c[1]) * t[1], ifx/v[1]>0 && y/w[1]>0

 

if i>1&& (x>=v[i] && y>=w[i])时,

令k=min(c[i],x/v[i],y/w[i]),k表示以背包的体积和重量能放入的第i种物品最多的件数。

f[i][x][y]=max{f[i-1][x][y],f[i-1][x-k*v[i]][y-k*w[i]] + k*t[i] |for all possible k},

else if i>1&& (x<v[i] || y<w[i])时,

f[i][x][y]=f[i-1][x][y],

 

看公式会有点晕,就分析第i种物品可否加入进背包?加几件(1件,2件,……,还是c[i]件)?是最好的,能产生最大价值。

 

注意:此题输入数据若较大的话,会产生较大的时间和空间。

实现过程若是如上所述的三维数组用四重循环填充,而后台测试数据有大至20 1000 500的数据,2~3秒是必须的了。

若想运行时间尽可能小,应对四重循环的最内层精简,少几次比较操作或写数组操作都是有效的。

 

另外,还可以将每种物品的多件看作捆绑的多件物品(1件,捆绑2件,…,捆绑c[i]件),

在填充之前先一次性扩展n种物品的体积数组,重量数组,价值数组,把扩展后的背包问题视为每种物品一件。

再用三重循环进行填充,大家可以试一试看运行时间如何?


++++++++++++++++++++++++++++++++++++++++++++++++++++++
源代码下载:http://download.csdn.net/detail/seanxu2012/5033818
++++++++++++++++++++++++++++++++++++++++++++++++++++++



  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值