该文是对dp的提高(并非是dp入门,dp入门者请先参考其他文章)

有时候dp的复杂度也有点大。。。会被卡。

这几次blog大多数会讲dp优化。

回归noip2017PJT4.(题目可以自己去百度)。就是个很好的案例。那题是个二分套dp如果dp不优化复杂度O(n^2logn)还能拿60分(CCF太仁慈了,如果是我直接给10分)。

正解加上个单调队列(其实是sliding window)O(nlogn)

我们发现,此类dp是这样的

状态i是由[l,r]转移过来的。且i在向右移动的过程中,[l,r]一定会跟着往右移,那不就是单调队列吗!!!

至于单调队列都不会的,我在这给一句解释———如果一个人比你小,还比你强,那你就永远比不过他了--chen_zhe大佬

其实是这样的——能转移到i的窗口[l,r]在向右移动的过程中,我们加一个队列,队首的dp值最优,在r向右移动时,遇到一个状态t

写个伪代码

while(队列不空&&t的dp值由于队尾值)弹出队尾元素;将t插入队尾

别忘了,l还要向右移动,右移会导致一些状态离开队列,需要在原队列删除。

OK接下来看例题:

多重背包n个物体,每个numi个,每个物品右价值和重量,求重量不超过m的最大价值(不会o(n^2m)请自行百度,改文不介绍过于基础的dp)。

您会说一句,这种水题我30s切。结果切完后就30分。。。。

一拍脑袋,二进制优化-》O(nmlogn)(将numi分解二进制,再用01做)

结果毒瘤的数据结构大师lxl成功卡掉了您的log(送你《凉凉》x1)

看来只能用O(nm)的做法,先写下dp转移方程

dp[i][j]表示前i个物体,限制重量为j的最大价值

dp[i][j]=max(dp[i-1][j-k*w[i]]+v[i]*k)(0<=k<=num[i])

状压:dp[j]=max(dp[j-k*w[i]]+v[i]*k)

我们先瞎搞:

在i和j都确定的情况下:

设:

n*w[i]+p=j p=j%w[i];

j/w[i]=n(注意是整除)

原方程变为dp[j]=max(dp[j%w[i]+k*w[i]]-k*w[i])+n*w[i](2)

聪明的你一定会了。

这个方程的k与原来的K不同(为区分下文将原来的K大写)

如果你自己推过(2),您会发现k=n-K

这样可以搞出k的范围

0<=n-k<=num[i]

n-num[i]<=k<=n

在j%w【i】不变时max(dp[j%w[i]+k*w[i]]-k*w[i])只与k有关,爽歪歪~~ 单调队列喽。

不懂再想想这张图(important)

没例题总不行!!例题是hdu1171(多重背包裸题)。但出题者非常善良,O(n^2m)也给过了。

单调队列79MS,纯dp1092MS

代码:

#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
][],v[],num[];
],l,r,n;
int main(){//freopen("in.txt","r",stdin);freopen("o1.txt","w",stdout);
    ){
        memset(dp,,,,sizeof(num));
        l=r=;
        ,j;
        ;i<=n;++i)scanf("%d%d",&v[i],&num[i]),sum+=v[i]*num[i];
        ,p,ans=;
        ;i<=n;++i){
            ;p<v[i];++p){
                int kl,kr;
                l=r=;l=;q[++r]=;
                for(j=p;j<=m;j+=v[i]){
                    int pre=kr;
                    kl=max(j/v[i]-num[i],),kr=j/v[i];
                    while(l<=r && (q[l]<kl || q[l]>kr))++l;
                    ;k<=kr;++k){
                        ^][j%v[i]+q[r]*v[i]]-q[r]*v[i]<dp[i%^][j%v[i]+k*v[i]]-k*v[i])--r;
                        q[++r]=k;
                    }
                    dp[i%][j]=dp[i%^][j%v[i]+q[l]*v[i]]-q[l]*v[i]+(j/v[i])*v[i];
                    ans=max(ans,dp[i%][j]);
                }
            }
        }
        printf("%d %d\n",sum-ans,ans);
    }
}

dp优化1——sgq(单调队列)的更多相关文章

  1. 【Codeforces 321E / BZOJ 5311】【DP凸优化】【单调队列】贞鱼

    目录 题意: 输入格式 输出格式 思路: DP凸优化的部分 单调队列转移的部分 坑点 代码 题意: 有n条超级大佬贞鱼站成一行,现在你需要使用恰好k辆车把它们全都运走.要求每辆车上的贞鱼在序列中都是连 ...

  2. BZOJ 2806 Luogu P4022 [CTSC2012]Cheat (广义后缀自动机、DP、二分、单调队列)

    题目链接: (bzoj) https://www.lydsy.com/JudgeOnline/problem.php?id=2806 (luogu) https://www.luogu.org/pro ...

  3. Dp优化之决策单调栈优化

    证明:g(i) ≤ g(j)   (i ≤ j) 令 d=g(i) , k<d , 设cut = x表示 f(i) = f(x) + w[x,i]    ( x < i ) 构造一个式子: ...

  4. 常见的DP优化类型

    常见的DP优化类型 1单调队列直接优化 如果a[i]单调增的话,显然可以用减单调队列直接存f[j]进行优化. 2斜率不等式 即实现转移方程中的i,j分离.b单调减,a单调增(可选). 令: 在队首,如 ...

  5. 【转】单调队列优化DP

    转自 : http://www.cnblogs.com/ka200812/archive/2012/07/11/2585950.html 单调队列是一种严格单调的队列,可以单调递增,也可以单调递减.队 ...

  6. 【HDU 3401 Trade】 单调队列优化dp

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=3401 题目大意:现在要你去炒股,给你每天的开盘价值,每股买入价值为ap,卖出价值为bp,每天最多买as ...

  7. [小明打联盟][斜率/单调队列 优化dp][背包]

    链接:https://ac.nowcoder.com/acm/problem/14553来源:牛客网 题目描述 小明很喜欢打游戏,现在已知一个新英雄即将推出,他同样拥有四个技能,其中三个小技能的释放时 ...

  8. bzoj 2806 [Ctsc2012]Cheat——广义后缀自动机+单调队列优化DP

    题目:https://www.lydsy.com/JudgeOnline/problem.php?id=2806 只想着怎么用后缀数据结构做,其实应该考虑结合其他算法. 可以二分那个长度 L .设当前 ...

  9. 「单调队列优化DP」P2034 选择数字

    「单调队列优化DP」P2034 选择数字 题面描述: 给定一行n个非负整数a[1]..a[n].现在你可以选择其中若干个数,但不能有超过k个连续的数字被选择.你的任务是使得选出的数字的和最大. 输入格 ...

随机推荐

  1. CEF与MLS快速交换对比

    MLS快速交换 到达某特定目的地址的IP包通常会引起数据包流,即假设交换过到特定目标的包之后,另一个很可能不久也会到达.通过构建最近交换目标的高速缓存,可以减少包在全路由表中查找同一目标的次数,这种“ ...

  2. POJ 2503 Babelfish(map,字典树,快排+二分,hash)

    题意:先构造一个词典,然后输入外文单词,输出相应的英语单词. 这道题有4种方法可以做: 1.map 2.字典树 3.快排+二分 4.hash表 参考博客:[解题报告]POJ_2503 字典树,MAP ...

  3. Apache-POI 简单应用

    测试的Excel文件为四列的普通表格 jar包:poi-3.15-beta2.jar(Office2003xls文件).poi-ooxml-3.15-beta2.jar(Office2007xlsx文 ...

  4. 在Tabbed Activity(ViewPager)中切换Fragment

    我用Android Studio的向导新建了一个Tabbed Activity,里面是ViewPager样式的,有三个tabs.如下: 但是我尝试在第一个tab中设置一个按钮,打开其他tab的时候,却 ...

  5. Stamps

    链接 分析:dp[i][j]表示前i个数,组成j,最少需要多少个.dp[i][j]=min(dp[i-1][j],dp[i-1][j-k*v[i]]+k),则可以转化为完全背包问题,同样的方法进行降维 ...

  6. js 图片上传

    可能很多不熟悉的图片上传的同学会觉得有点懵,其实做过一次你就会发现特别的简单. 只是一个formData格式的表单提交,把地址写到 action = "" 里面就可以了,当然你可以 ...

  7. alter table *** add constraint *** 用法---约束

    1.主键约束:要对一个列加主键约束的话,这列就必须要满足的条件就是分空因为主键约束:就是对一个列进行了约束,约束为(非空.不重复)以下是代码   要对一个列加主键,列名为id,表名为emp 格式为:a ...

  8. 设置一个.exe文件开机启动

    运行"regedit",编辑注册表 HKEY_LOCAL_MACHINE -- SOFTWARE -- Microsoft -- Windows -- CurrentVersion ...

  9. iterator与iterable的区别和联系

    iterator与iterable   用Iterator模式实现遍历集合Iterator模式是用于遍历集合类的标准访问方法.它可以把访问逻辑从不同类型的集合类中抽象出来,从而避免向客户端暴露集合的内 ...

  10. eclipse必备快捷键

    1.[ Ctrl + Shift+ P  ],查找括号的开始和闭合 2.[ALT+/],这个快捷键应该没有人不知道 3.[Ctrl+O],显示类中方法和属性的大纲,能快速定位类的方法和属性,在查找Bu ...