Description
在《Harry Potter and the Deathly Hallows》中,Harry Potter他们一起逃亡,现在有许多的东西要放到赫敏的包里面,但是包的大小有限,所以我们只能够在里面放入非常重要的物品,现在给出该种物品的数量、体积、价值的数值,希望你能够算出怎样能使背包的价值最大的组合方式,并且输出这个数值,赫敏会非常地感谢你。
Input
(1)第一行有2个整数,物品种数n和背包装载体积v。
(2)2行到n+1行每行3个整数,为第i种物品的数量m、体积w、价值s。
Output
仅包含一个整数,即为能拿到的最大的物品价值总和。
Sample Input
2 10
3 4 3
2 2 5
Sample Output
13
范围
1<=v<=500
1<=n<=2000
1<=m<=5000
1<=w<=20
1<=s<=100
思路
题目背景挺好,题目范围挺大,T的次数挺多 这道题2个解法,第一个多重背包传统解法+快读,第2个2进制拆分,这里重点讲第2种。 这里和传统的01背包框架一样,但是我们对于每一个正整数n(即第j个物品的个数),看ta的2进制形式,然后,我们把2进制下的每一位作为一个物品,体积为w该位位权,价值为v该位位权,为了节约空间,当该位为0时,不做处理
具体的,设tot为最后物品个数
那么,我们该如何拆分呢?
int o=1;//为位权
while (g>=o)//g为个数
{
tot++;
w[tot]=z*o;//体积
gj[tot]=jg*o;//价值
g-=o;
o*=2;
}
if (g!=0)//这里处理g没有被清理完的情况(如g原来为8)
{
tot++;
w[tot]=z*g;
gj[tot]=jg*g;
}
方程:
b
[
k
]
=
m
a
x
(
b
[
k
]
,
b
[
k
−
w
[
j
]
]
+
g
j
[
j
]
)
(
1
<
=
j
<
=
t
o
t
,
v
>
=
k
>
=
w
[
j
]
)
b[k]=max(b[k],b[k-w[j]]+gj[j])(1<=j<=tot,v>=k>=w[j])
b[k]=max(b[k],b[k−w[j]]+gj[j])(1<=j<=tot,v>=k>=w[j])
code:
#include<iostream>
#include<cstdio>
#include<algorithm>
using namespace std;
int b[700],n,v,g,z,jg,w[100001],gj[100001],tot;
int main()
{
scanf("%d%d",&n,&v);
for (int i=0;i<n;i++)
{
scanf("%d%d%d",&g,&z,&jg);
int o=1;
while (g>=o)
{
tot++;
w[tot]=z*o;
gj[tot]=jg*o;
g-=o;
o*=2;
}
if (g!=0)
{
tot++;
w[tot]=z*g;
gj[tot]=jg*g;
}
}
for (int j=1;j<=tot;j++)
{
for (int k=v;k>=w[j];k--)
{
b[k]=max(b[k],b[k-w[j]]+gj[j]);
}
}
cout<<b[v];
return 0;
}