题目描述

在之前的上机中,零崎已经出过了01背包和完全背包,也介绍了使用-1初始化容量限定背包必须装满这种小技巧,接下来的背包问题相对有些难度,可以说是01背包和完全背包的进阶问题。

多重背包:物品可以有0-n件。

对于第i种物品,我们有取0件,1件…n [ i ] 件共n [ i ] +1种策略,状态转移方程为f [ i ] [ v ] = max { f [ i - 1 ] [ v - k × c [ i ] ] + k × w [ i ] | 0 <=k<= n [ i ] }。在这里,很自然的有一种策略可以将其转化为01背包,即将物品换为n[i]件01背包中的物品,但是复杂度为O(VΣni),时间复杂度没有降低。实际上,对于所有类似情况,我们都可以利用二进制求和来降低时间复杂度。即将物品替换为价值和费用 * 系数=1,2,2^2,…,2^k,n[i]-2^k+1的物品。系数之和为n [ i ],表明不能取到多于n [ i ]件物品,但可以取到0…n[ i ]中任意一个整数件。利用这一优化,算法事件复杂度可以降到O(VΣlogni)。

实际上F [ i ] [ j ] 只依赖于 F [ i-1 ] [ j - k * w [ i ] ],这里依赖项之间构成了一个 { j mod w [ i ] }剩余类,不同剩余类之间无关,注意到这点利用单调队列,每个状态均摊O(1)的时间,可以进一步将算法时间复杂度优化至O(VN)级别的,不过在此不再详细阐述。(其实也就是NOIP程度,放在大学应该可以接受,但是这个优化个人感觉已经脱离dp)

DD大牛给出的伪代码。
def MultiplePack(F,C,W,M)
if C * M >= V
CompletePack(F,C,W)
return //考虑这里为什么可以直接用完全背包
k := 1
while k < M
ZeroOnePack(kC,kW)
M := M - k
k := 2k
ZeroOnePack(C M,W M)

输入

第一个数为数据组数n 1<=n<=10

接下来n组测试数据,每组测试数据由2部分组成。

第一行为背包容量V,物品种类数N。1<=V<=30000,1<=N<=200

接下来N行每行三个数为物品价值v,物品重量w,物品件数M。

1<=v,w<=200, 1<=M<=25

输出

对于每组数据,输出一行,背包能容纳的最大物品价值

输入样例

1
10 2
1 2 3
2 3 2

输出样例

6

题目来源:http://biancheng.love/contest/10/problem/E/index
解题思路:
问题属于背包问题,同时包括了0-1和完全背包,因此为多重背包问题。
按照之前的想法,只要判断每件物品的件数,可以确定对于该物品是使用0-1背包还是完全背包。
0-1背包的代码:
 void Zeronepack(int w,int v)
{
for(int i=V; i>=w; i--)
if(dp[i]<dp[i-w]+v)
dp[i]=dp[i-w]+v;
}

完全背包的代码:

 void Compack(int w,int v)
{
for(int i=w; i<=V; i++)
if(dp[i]<dp[i-w]+v)
dp[i]=dp[i-w]+v;
}

本题需要利用0-1背包以及完全背包来解决多重背包问题

代码:

 #include <bits/stdc++.h>
#include<stdio.h>
#include<string.h>
int dp[];
int V,N;
void Compack(int w,int v)
{
for(int i=w; i<=V; i++)
if(dp[i]<dp[i-w]+v)
dp[i]=dp[i-w]+v;
} void Zeronepack(int w,int v)
{
for(int i=V; i>=w; i--)
if(dp[i]<dp[i-w]+v)
dp[i]=dp[i-w]+v;
} int main()
{
int kase,v,w,m;
scanf("%d",&kase);
while(kase--)
{
memset(dp,,sizeof(dp));
scanf("%d%d",&V,&N);
for(int i=; i<=N; i++)
{
scanf("%d%d%d",&v,&w,&m);
if(w*m>=V)
Compack(w,v);
else
{
for(int j=; j<m; j<<)
{
Zeronepack(j*w,j*v);
m-=j;
}
Zeronepack(m*w,m*v);
}
}
printf("%d\n",dp[V]);
}
return ;
}

DP大作战——多重背包的更多相关文章

  1. DP大作战—组合背包

    题目描述 组合背包:有的物品只可以取一次(01背包),有的物品可以取无限次(完全背包),有的物品可以取的次数有一个上限(多重背包). DD大牛的伪代码 for i = 1 to N if 第i件物品属 ...

  2. AlvinZH掉坑系列讲解(背包DP大作战H~M)

    本文由AlvinZH所写,欢迎学习引用,如有错误或更优化方法,欢迎讨论,联系方式QQ:1329284394. 前言 动态规划(Dynamic Programming),是一个神奇的东西.DP只能意会, ...

  3. 963 AlvinZH打怪刷经验(背包DP大作战R)

    963 AlvinZH打怪刷经验 思路 这不是一道普通的01背包题.大家仔细观察数据的范围,可以发现如果按常理来的话,背包容量特别大,你也会TLE. 方法一:考虑01背包的一个常数优化----作用甚微 ...

  4. 976 AlvinZH想回家(背包DP大作战T)

    976 AlvinZH想回家 思路 如果在第i小时有一些飞机延误,那么一架飞机的c值越大,这一小时产生的损失也越大.而使这一小时产生的损失尽可能的小并不会导致接下来时间产生的损失增大.因此应当每一小时 ...

  5. 977 AlvinZH过生日(背包DP大作战S)

    977 AlvinZH过生日 思路 难题.逆推DP. 要明确dp的状态只与是否有选择权有关,而与选择权在谁手里无关.因为不论选择权在谁手里,那个人都会尽可能的获得最大的蛋糕重量. dp[i]表示分配到 ...

  6. 991 AlvinZH的奇幻猜想----整数乘积plus(背包DP大作战P)

    914 AlvinZH的奇幻猜想----整数乘积puls 思路 难题.动态规划. 将数字串按字符串输入,处理起来更方便些. dp[i][j]:表示str[0~i]中插入j个乘号时的乘积最大值.状态转移 ...

  7. 906 AlvinZH的奇幻猜想----整数乘积(背包DP大作战O)

    906 AlvinZH的奇幻猜想----整数乘积 思路 难题.动态规划. 将数字串按字符串输入,处理起来更方便些. dp[i][j]:表示str[0~i]中插入j个乘号时的乘积最大值.状态转移方程为: ...

  8. 851 AlvinZH的鬼畜密码(背包DP大作战N)

    851 AlvinZH的鬼畜密码 思路 难题.动态规划. 先判断字符串是否合理(可翻译),然后分段处理,每一小段用动态规划求出解法数. dp[i]:字符串str[0~i]的解法数.通过判断str[i] ...

  9. DP大作战—状态压缩dp

    题目描述 阿姆斯特朗回旋加速式阿姆斯特朗炮是一种非常厉害的武器,这种武器可以毁灭自身同行同列两个单位范围内的所有其他单位(其实就是十字型),听起来比红警里面的法国巨炮可是厉害多了.现在,零崎要在地图上 ...

随机推荐

  1. python常用数据类型内置方法介绍

    熟练掌握python常用数据类型内置方法是每个初学者必须具备的内功. 下面介绍了python常用的集中数据类型及其方法,点开源代码,其中对主要方法都进行了中文注释. 一.整型 a = 100 a.xx ...

  2. IOS开发UI基础之UIButton

    什么是按钮?

  3. Python+Selenium进行UI自动化测试项目中,常用的小技巧4:日志打印,longging模块(控制台和文件同时输出)

    在前段时间,为了给项目中加入日志功能,就想到了 logging 模块,百度logging一大推,都是各种复制的,并没有找到自己想要的结果:我的目的很简单,就是:在把日志写入文件的同时在控制台输出,更加 ...

  4. C#学习笔记(1) --简叙.net体系结构

    1 C#与.NET的关系 (1) C#是专门为与Microsoft的.Net Framework一起使用而设计的. (2) C#是一种基于面向对象设计方法的的语言. (3) 需要注意的是,C#就其本身 ...

  5. spring事件通知机制详解

    优势 解耦 对同一种事件有多种处理方式 不干扰主线(main line) 起源 要讲spring的事件通知机制,就要先了解一下spring中的这些接口和抽象类: ApplicationEventPub ...

  6. php学习笔记:利用递归实现删除文件目录

    直接删除目录,如果是空目录是可以删除,如果不是空目录,这时候只能先删除目录里面的文件,然后再删除目录.我封装了个删除函数,然后直接调用这个函数.喜欢的可以直接拿去用,编码是gbk的,使用时候注意下编码 ...

  7. Docker有什么好处?

    Docker背后的想法是创建软件程序可移植的轻量容器,让其可以在任何安装了Docker的机器上运行,而不用关心底层操作系统,类似船舶使用的集装箱,野心勃勃的他们成功了. Docker可以解决虚拟机能够 ...

  8. iscroll性能

    iscroll是比较耗性能的,在iPhone和性能比较好的机是比较流畅的,在性能低的手机就会出现卡的情况.所以如果不想出现这种情况,只有不使用iscroll,囧.

  9. CSS3选择器(一)

    E[att^='val'] 选择属性值以val开头的任何字符 E[att$='val'] 选择属性值以val结尾的任何字符 E[att*='val'] 选择属性值包含val的任何字符 :root HT ...

  10. echarts 地图图

    效果如下图: 1.下载echarts对应包: http://echarts.baidu.com/ 2.前端页面: <!DOCTYPE html> <html xmlns=" ...