[DP之多重背包优化方法]
首先我们看一道有趣的题目

然后这道题很快想到是一个多重背包和无限背包混合体
那么我们就以这道题 来讨论一下多重背包的优化
首先我们看看朴素打法
memset(F,,sizeof(F)); F[]=;
for(int i=;i<=N;i++)
for(int k=;k<=C[i];k++)
for(int j=T*;j>=;j--)
if(j-V[i]>=) F[j]=min(F[j],F[j-V[i]]+);
很简单 很好懂 但是这样做导致时间复杂度为O(N*C*T) 这道题来看超时到爆炸
那么我们考虑两种方法 第一种是像wph写的 首先贪心一会儿 然后再背包 答案大概在T到2*T的范围内
但是这种方法导致代码很玄学 因为贪心的时候很有可能有一些东西处理不到
那么我们考虑第二种方法 就是优化多重背包 因为无限背包的时间是足够的
优化多重背包有两种算法,但是下面只介绍最快的:
1.用二进制优化 这个好像我有写过 但不知道怎么打和原理了 陈年老事 具体可以问wph 时间复杂度O(NTlog(C))
2.可以用单调队列进行优化 时间复杂度为O(NT)
我只讨论单调队列优化 我们先列出有
F[i][j]=min(F[i-1][j-vi*k]+k) (0<=k<=ci)
那么我们发现 每一次都是和vi有关的 我们其实可以把式子变一下
令a=j/v[i] b=j%v[i] j=a*v[i]+b
F[j]=min(F[b+k*v[i]]-k)+a (a-c[i]<=k<=a)
我们把k枚举 就是单调队列了,具体看下面
其实我们在做j这个状态的时候 k和a是相同的 当然方便理解 因为以前的是k 现在的是a 只是对于当前来说我的a和k是一样 但是对于别的来说 我就要找最小的k
我们可以枚举b 然后可以每次都 +v[i] 处理 这样的话每一次每个位置只会被扫1遍 大大减少了时间 所以时间复杂度为O(NT)很显然
memset(F,,sizeof(F)); F[]=;
for(int i=;i<=N;i++)
{
for(int j=;j<=;j++) G[j]=F[j]; for(int b=;b<V[i];b++)
{
head=; tail=;
for(int j=b;j<=;j+=V[i])
{
int a=j/V[i];
while(head<=tail&&Q[head].first<a-C[i]) head++;
if(head<=tail) F[j]=min(G[j],Q[head].second+a);
while(head<=tail&&Q[tail].second>=G[j]-a) tail--;
Q[++tail]=make_pair(a,G[j]-a); }
}
}
良心的贴一道这道例题的链接 这里
[DP之多重背包优化方法]的更多相关文章
- 单调队列优化DP,多重背包
单调队列优化DP:http://www.cnblogs.com/ka200812/archive/2012/07/11/2585950.html 单调队列优化多重背包:http://blog.csdn ...
- dp之多重背包(二进制优化)
void solve(int v,int w,int c){ int count=0; for(int k=1;k<=c;k<<=1) { val[c ...
- 硬币问题 (dp,多重背包的二分优化)
题目描述 给你n种硬币,知道每种的面值Ai和每种的数量Ci.问能凑出多少种不大于m的面值. 输入 有多组数据,每一组第一行有两个整数 n(1≤n≤100)和m(m≤100000),第二行有2n个整数, ...
- hdu1059&poj1014 Dividing (dp,多重背包的二分优化)
Problem Description Marsha and Bill own a collection of marbles. They want to split the collection a ...
- HDU 3732 Ahui Writes Word 多重背包优化01背包
题目大意:有n个单词,m的耐心,每个单词有一定的价值,以及学习这个单词所消耗的耐心,耐心消耗完则,无法学习.问能学到的单词的最大价值为多少. 题目思路:很明显的01背包,但如果按常规的方法解决时间复杂 ...
- dp之多重背包hdu1059
题意:价值为1,2,3,4,5,6. 分别有n[1],n[2],n[3],n[4],n[5],n[6]个.求能否找到满足价值刚好是所有的一半的方案. 思路:简单的多重背包,我建议多重背包都用二进制拆分 ...
- hdu1059(多重背包优化)
使用一种二进制的优化, 可以完美的解决这题,<背包九讲>中说的非常好 但是还有一种线性复杂的算法. 应该算是该题很巧妙的解法 ;i++) { ;l--) { ) continue; ;k& ...
- nyoj 546——Divideing Jewels——————【dp、多重背包板子题】
Divideing Jewels 时间限制:1000 ms | 内存限制:65535 KB 难度:4 描述 Mary and Rose own a collection of jewells. ...
- hdu 1059 Dividing(多重背包优化)
Dividing Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others)Total Su ...
随机推荐
- sql简单实用的统计汇总案例参考
USE [PM]GO/****** 对象: StoredProcedure [dbo].[LfangSatstics] 脚本日期: 08/24/2013 10:57:48 ******/SET ...
- [转]Android与电脑局域网共享之:Samba Client
在上一篇文章中我提到如何在Android手机上建立Windows共享服务器,现在来说说一个反向的问题,就是,如何在Android手机上访问Windows计算机中的共享资源,当然,前提也是需要软件,这里 ...
- mac下安装配置java jdk,maven,resin
mac jdk安装及环境变量配置 安装http://www.ifunmac.com/2013/04/mac-jdk-7/ jdk安装目录:/Library/Java/JavaVirtualMachin ...
- 浅谈PHP在各系统平台下的换行符
<?php echo 'aaa\n';//用于linux.unix平台C的换行也是如此 echo 'bbb\r';//用于mac平台 echo 'ccc\r\n';//用于windows平台 / ...
- SZU:A66 Plastic Digits
Description There is a company that makes plastic digits which are primarily put on the front door o ...
- Ajax+Ashx实现以及封装成控件的实现
asp.net 后台多线程异步处理时的 进度条实现一(Ajax+Ashx实现以及封装成控件的实现) 工作好长时间了,这期间许多功能也写成了不少的控件来使用,但是,都只是为了代码的结构清析一些而已.而这 ...
- Python Learing(二):Basic Image Processing 1
<写在前面> Basic image processing 1: 0.(以简单的曲线图为例)对于生成的图自定义外观,使用子图,多个数据集,标题,标签,交互式标注,图例: 1.生成散点图,直 ...
- 【C++ 中文手册】即将完成
[C++ 中文手册]即将完成 内容包含C++11,历时一年,日夜赶工,即将完成! 该参考手册主要由以下四部份内容组成: C++ 语言 C++ 继承了 C 语言 的大部分语法,并在其基础上修改或增加部分 ...
- .NET面向对象特性之封装
.NET面向对象特性之封装 面向对象的基本内容由:类.对象.属性.方法.字段构成. 面向对象的三大特性:继承.多态.封装. 关于面向对象的特性很多人都把目光转向了继承.多态和接口,却很少有人提及过封装 ...
- Orchard是一个了不起CMS(内容管理系统)
在这个系列中,我们将共同经历从头开始构建一个Orchard模块的过程! 虽然Orchard是一个了不起CMS(内容管理系统),有着强大的功能和令人振奋的架构,可以无限的扩展,但它可能需要花费一定时间, ...