一、分组背包问题
1.定义
分组背包,通俗的讲就是,给你N组(物品是分组的 )物品,然后每一组你至多选择一个物品(也可以不选),每个物品都有自己的体积和价值,现在给你一个容里为M的背包,让你用这个背包装物品,使得物品价值总和最大.
2.解释
其实就类似于01背包,对于一个物品有两种决策选或不选,但是分组背包是在01背包的基础上对物品进行了分组,并且每一组只能最多选择一个物品,
我们设f[i][j]为当前考虑到了第i组物品,剩余容里为j的背包能装物品的最大价值,那么很容易想到我们需要去枚举第i组物品,考虑选哪一个物品时最优的(或者不选)
就是i f ( j > = v [ i ] [ k ] ) f [ i ] [ j ] = m a x ( f [ i ] [ j ] , f [ i − 1 ] [ j − v [ i ] [ k ] ] + w [ i ] [ k ] )
v[i][k]和w[i][k]分别表示第i组物品中第k个物品的体积和价值
代码
for(int i=1;i<=n;i++)//物品
for(int j=0;j<=m;j++)//容量(体积)
for(int k=1;k<=s[i];k++)//s[i]表示第i组物品的个数(遍历第i组的物品)
if(j>=v[i][k])//剩余的背包容量j大于第i组的第k个物品的体积
{
f[i][j] = max(f[i][j],f[i-1][j-v[i][k]]+w[i][k]);
}
二、多重背包问题
1.定义
有N种物品和一个容量为V的背包。第i种物品最多有n[i]件可用,每件费用是c[i],价值是w[i]。求解将哪些物品装入背包可使这些物品的费用总和不超过背包容量,且价值总和最大。
2.解释
既然物品个数有限,但还要判断要装几个,我们可以用暴力的做法,三重循环,每层循环控制自己的变量,容易理解。第三层循环就是控制装的物品的个数,我们通过分析可以得知,在使用次数不超过物品提供个数的同时,还要小于背包的空间限制。
代码实现
for(int i=1;i<=n;i++)//选几件物品
for(int j=1;j<=m;j++)//从小的体积 开始依次推导
{
for(int k=0;k<=s[i]&&j>=k*v[i];k++)//第i件物品 选了k件 (s[i]是第i件物品的件数)
{
f[i][j]=max(f[i][j],f[i-1][j-k*v[i]]+k*w[i]);
}
}