多重背包:

基本思路:

先来看一个引例:有N种物品和一个容量为V的背包。第i种物品最多有n[i]件可用,每件费用是c[i],价值是w[i]。求解将哪些物品装入背包可使这些物品的费用总和不超过背包容量,且价值总和最大。这种类型的背包问题的特点是:每件物品的件数有限。

和完全背包问题很类似。基本的方程只需将完全背包问题的方程略微一改即可,因为对于第i种物品有n[i]+1种策略:取0件,取1件„„取n[i]件。令f[i][v]表示前i种物品恰放入一个容量为v的背包的最大权值,则有状态转移方程:f[i][v]=max{f[i-1][v-k*c[i]]+k*w[i]|0<=k<=n[i]} 完全背包中k的范围是(0<=k<=v/c[i]). 复杂度是O(V*Σn[i]),

代码与完全背包的区别仅在内部循环上由

1
for(k = 1; k <= j/weight[i]; ++k)

变为

1
for(k = 1; k <=n[i] && k<=j/weight[i]; ++k)

多重背包二进制拆分实现

跟完全背包一样的道理,利用二进制的思想将n[i]件物品i拆分成若干件物品,目的是在0-n[i]中的任何数字都能用这若干件物品代换,另外,超过n[i]件的策略是不允许的。

方法是将物品i分成若干件,其中每一件物品都有一个系数,这件物品的费用和价值都是原来的费用和价值乘以这个系数,使得这些系数分别为1,2,4,…,2^(k-1),n[i]-2^k+1,且k满足n[i]-2^k+1>0的最大整数。例如,n[i]=13,就将该物品拆成系数为1、2、4、6的四件物品。分成的这几件物品的系数和为n[i],表明不可能取多于n[i]件的第i种物品。另外这种方法也能保证对于0..n[i]间的每一个整数,均可以用若干个系数的和表示。

 #include <iostream>
using namespace std; /* 多重背包 二进制拆分
* Time Complexity 大于O(N*V)
* Space Complexity O(N*V)
* 设 V <= 200 N <= 10 ,拆分后 物品总数 < 50
* 每件物品有 log n[i]种状态
*/ int maxV[];
int weight[]; /* 记录拆分后物体重量 */
int value[]; /* 记录拆分后物体价值 */
int V, N; void main()
{
int i, j;
scanf("%d %d",&V, &N);
int weig, val, num;
int count = ; for(i = ; i < N; ++i)
{
scanf("%d %d %d",&weig,&val,&num); for(j = ; j <= num; j <= ) // 二进制拆分
{
weight[count] = j * weig;
value[count++] = j * val;
num -= j;
}
if(num > )
{
weight[count] = num * weig;
value[count++] = num * val;
}
}
for(i = ; i < count; ++i) // 使用01背包
{
for(j = V; j >= weight[i]; --j)
{
int tmp = maxV[j-weight[i]] + value[i];
maxV[j] = maxV[j] > tmp ? maxV[j] : tmp;
}
}
printf("%d",maxV[V]);
} /*
【输入样例】
4 20
3 9 3
5 9 1
9 4 2
8 1 3
【输出样例】
47
*/

下面给出O(log amount)时间处理一件多重背包中物品的过程,其中amount表示物品的数量:

 void multiplepack(int cost, int weight, int amount)
{
if(cost*amount>=V)
cmpletepack(cost,weight);
else
{
int k=;
while(k<amount)
{
zeroonepack(k*cost,k*weight);
amount-= k;
k=k*;
}
zeroonepack(amount*cost,amount*weight);
}
}

总结完啦~要回家了已经做不进去题了~噶呜~但我还在坚持每天更新博客~*。*

随机推荐

  1. nginx sendfile tcp_nopush tcp_nodelay参数解释

    sendfile 现在流行的web 服务器里面都提供 sendfile 选项用来提高服务器性能,那到底 sendfile是什么,怎么影响性能的呢?sendfile实际上是 Linux2.0+以后的推出 ...

  2. 04-OC属性的使用、自动释放池、封装和继承

    目录: 一.IOS6声明式属性的使用 二.autoreleasepool自动释放池 三.封装.继承 回到顶部 一.IOS6声明式属性的使用 注:声明式属性默认情况下,并没有解决内存问题, 当使用@pr ...

  3. 基于Andoird 4.2.2的Account Manager源代码分析学习:AccountManagerService系统服务的添加

    从启动说起 Android系统加载时,首先启动init进程,该进程会启动Zygote进程.Zygote进程执行/system/bin/app_process程序.app_process程序在执行中,通 ...

  4. Linux下基于Erlang的高并发TCP连接压力实验

    1.实验环境: 联想小型机: 操作系统:RedHat Enterprise LinuxServer release6.4(Santiago) 内核版本号:Linux server1 2.6.32-35 ...

  5. .net版Git Server --- bonobo

    官网地址: https://bonobogitserver.com/ Demo: http://demo.bonobogitserver.com/Home/LogOn  登入admin:admin C ...

  6. C++ Primer学习笔记2--c++标准库中的 vector、string 和 bitset 类型

    一.string    #include <string>  using std::string    初始化函数:    string s1;        默认构造函数 s1 为空串 ...

  7. CodeForces 446B DZY Loves Modification

    题意: k次操作  每次选择一行或一列  得到所选数字的和  并将所选数字同一时候减去p  问最多得到多少 思路: 重点在消除行列间的相互影响 因为每选一行全部列所相应的和都会-p  那么假设选了i次 ...

  8. leetcode——Search a 2D Matrix 二维有序数组查找(AC)

    Write an efficient algorithm that searches for a value in an m x n matrix. This matrix has the follo ...

  9. makefile 必知必会

    Makefile 必知必会 Makefile的根本任务是根据规则生成目标文件. 规则 一条规则包含三个:目标文件,目标文件依赖的文件,更新(或生成)目标文件的命令. 规则: <目标文件>: ...

  10. Kendo UI开发教程(22): Kendo MVVM 数据绑定(十一) Value

    Value绑定可以把ViewModel的某个属性绑定到DOM元素或某个UI组件的Value属性.当用户修改DOM元素或UI组件的值时,绑定的ViewModel的值也随之发生改名.同样,如果ViewMo ...