首先我们看一道有趣的题目

然后这道题很快想到是一个多重背包和无限背包混合体

那么我们就以这道题 来讨论一下多重背包的优化

首先我们看看朴素打法

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之多重背包优化方法]的更多相关文章

  1. 单调队列优化DP,多重背包

    单调队列优化DP:http://www.cnblogs.com/ka200812/archive/2012/07/11/2585950.html 单调队列优化多重背包:http://blog.csdn ...

  2. dp之多重背包(二进制优化)

    void solve(int v,int w,int c){    int count=0;    for(int k=1;k<=c;k<<=1)    {        val[c ...

  3. 硬币问题 (dp,多重背包的二分优化)

    题目描述 给你n种硬币,知道每种的面值Ai和每种的数量Ci.问能凑出多少种不大于m的面值. 输入 有多组数据,每一组第一行有两个整数 n(1≤n≤100)和m(m≤100000),第二行有2n个整数, ...

  4. hdu1059&poj1014 Dividing (dp,多重背包的二分优化)

    Problem Description Marsha and Bill own a collection of marbles. They want to split the collection a ...

  5. HDU 3732 Ahui Writes Word 多重背包优化01背包

    题目大意:有n个单词,m的耐心,每个单词有一定的价值,以及学习这个单词所消耗的耐心,耐心消耗完则,无法学习.问能学到的单词的最大价值为多少. 题目思路:很明显的01背包,但如果按常规的方法解决时间复杂 ...

  6. dp之多重背包hdu1059

    题意:价值为1,2,3,4,5,6. 分别有n[1],n[2],n[3],n[4],n[5],n[6]个.求能否找到满足价值刚好是所有的一半的方案. 思路:简单的多重背包,我建议多重背包都用二进制拆分 ...

  7. hdu1059(多重背包优化)

    使用一种二进制的优化, 可以完美的解决这题,<背包九讲>中说的非常好 但是还有一种线性复杂的算法. 应该算是该题很巧妙的解法 ;i++) { ;l--) { ) continue; ;k& ...

  8. nyoj 546——Divideing Jewels——————【dp、多重背包板子题】

    Divideing Jewels 时间限制:1000 ms  |  内存限制:65535 KB 难度:4   描述 Mary and Rose own a collection of jewells. ...

  9. hdu 1059 Dividing(多重背包优化)

    Dividing Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)Total Su ...

随机推荐

  1. 【转】android创建Popwindow弹出菜单的两种方式

    方法一的Activity package com.app.test02; import android.app.Activity; import android.os.Bundle; import a ...

  2. Django数据库迁移

    如果你用过Django的数据库就会发现一个比较令人纠结的地方:数据库更改. 我们知道添加或者删除一个models.Model 需要在数据库里相应的操作,这需要我们进入数据库命令行手动添加或删除,因为s ...

  3. CentOS上搭建java WEB开发环境Tomcat+MySQL+JDK

    对于初学者来说,想在linux系统上搭建一个java web服务器,不知道什么方案可行, 这篇文章主要是告诉这些基础和概念相对薄弱的同学,这样搭建是可行的,大体上没问 题的,出问题也是细节问题.所以此 ...

  4. 利用servicestack连接redis

    利用servicestack连接redis 引言:作为少有的.net架构下的大型网站,stackoverflow今日发表了一篇文章,介绍了其技术体系,原文链接http://highscalabilit ...

  5. 启动mysql错误解决方案,学会查看错误日志:mysql.sock丢失,mysqld_safe启动报错

    本人还是个菜鸟,下面是我的经验之谈,能解决一些问题,有不对的地方,敬请斧正. 我的是CentOS6.3+MySQL5.1.57. 重启了一次服务器后,使用> mysql -u root -p登陆 ...

  6. 2013 多校联合 2 A Balls Rearrangement (hdu 4611)

    Balls Rearrangement Time Limit: 9000/3000 MS (Java/Others)    Memory Limit: 65535/32768 K (Java/Othe ...

  7. php memcached+Mysql(主从)

    /* index.php   程序入口,用来构造sql(如查询,更新) config.php  配置参数(memcache,mysql) init.php    封装memcached操作(memca ...

  8. 使用DOM4J解析XML文档,以及使用XPath提取XML文档

    使用DOM4J解析XML文档 需要首先下载DOM4J工具包.这是个第三方工具包 在使用DOM4J解析的时候需要导入 DOM4J的JAR包 下载DOM4J工具包->在MyEclipse中新建lib ...

  9. 深入浅出MyBatis-Sqlsession

    前面的章节主要讲mybatis如何解析配置文件,这些都是一次性的过程.从本章开始讲解动态的过程,它们跟应用程序对mybatis的调用密切相关.本章先从sqlsession开始. 创建 正如其名,Sql ...

  10. phper談談最近重構代碼的感受(1)

    作爲一個工作時間並不算長的phper,卻參與了兩家公司的代碼重構.下面談談我的一些感受. 在mjm公司,當時我負責日常的需求開發和2.0的重構.當初的重構更多的是clean codes和一些代碼規範上 ...