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
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
++++++++++++++++++++++++++++++++++++++++++++++++++++++