单调队列:就是滑动窗口,可以求出定长 RMQ,时间复杂度线性。

优化 DP

首先把dp方程写成这个样子:

或者其他运算f[i]=max(或者其他运算){f[j]+calc(i,j)}<script type="math/tex;mode=inline" id="MathJax-Element-3">f[i] = max(\text{或者其他运算})\{f[j]+calc(i,j)\}</script>f[i] = max(\text{或者其他运算})\{f[j]+calc(i,j)\}

注意 calc 的计算要能只和 j 有关。

同时 j 满足一个定长的范围,也就是说转移是从一个定长区间来的。

P3572 [POI2014] PTA-Little Bird,P1725 琪露诺:完全的模版。

在此不妨以P3957 [NOIP2017 普及组] 跳房子为例。

首先意识到本题答案满足单调性,灵活性的定义也符合人类想象(越灵活,可能得到的答案就越大),于是首先二分 k 的值,然后考虑 k 确定时的做法。

根据题目灵活性的定义,实际上能跳的范围就是 [max(d−g,1),d+g]<script type="math/tex;mode=inline" id="MathJax-Element-1">[\max(d-g,1),d+g]</script>[\max(d-g,1),d+g] ,满足定长区间, f[i]=f[j]+s[i]<script type="math/tex;mode=inline" id="MathJax-Element-2">f[i]=f[j]+s[i]</script>f[i]=f[j]+s[i] ,那么使用单调队列。

结合一下我的代码:

#include <bits/stdc++.h>
#define int long long
#define U (l+r)/2
#define F(i,a,b) for(int i=(a);i<=(b);i++)
using namespace std;
const int N=500005,M=(N<<1),inf=1e18;
int n,d,k,x[N],s[N],f[N],q[M];
int ck(int g){
int h=1,t=0,l=0;
fill(f+1,f+n+1,-inf);
F(i,1,n){
while(h<=t&&x[i]-x[q[h]]>d+g) h++;
while(l<i&&x[i]-x[l]>=d-g){
while(h<=t&&f[l]>=f[q[t]])t--;
q[++t] = l++;
}if(h<=t)f[i]=f[q[h]]+s[i];
if(f[i]>=k) return 1;
}return 0;
}
signed main(){
ios_base::sync_with_stdio(false);cin.tie(0);cout.tie(0);
cin>>n>>d>>k;F(i,1,n) cin>>x[i]>>s[i];
int l=0,r=1e9,ans=-1;while(l<=r)
ck(U)?ans=U,r=U-1:l=U+1;
cout<<ans; return 0;
}

首先,对超出范围的,进行删除,然后对符合条件的,进行加入,最后直接转移答案。

CF372C Watching Fireworks is Fun

这题有点启示作用,当 k 满足 j−x<k<j<script type="math/tex;mode=inline" id="MathJax-Element-4">j-xj-x<k<j 的时候显然直接单调队列。然而这道题会推出来一个这样的式子: j−x<k<j+x<script type="math/tex;mode=inline" id="MathJax-Element-9">j-xj-x<k<j+x 。做法是拆成两段,一段满足 j−x<k≤j<script type="math/tex;mode=inline" id="MathJax-Element-5">j-xj-x<k\le j ,另一段是 j≤k<j+x<script type="math/tex;mode=inline" id="MathJax-Element-6">j\le kj\le k<j+x ,可以两次单调队列秒掉。

具体的,我们把状态设为 f[i][j]<script type="math/tex;mode=inline" id="MathJax-Element-8">f[i][j]</script>f[i][j] ,表示放第 i 个烟花的时候在 j 点能得到的最大值, f[i][j]=max{f[i−1][k]+b[i]−|a[i]−j|}<script type="math/tex;mode=inline" id="MathJax-Element-7">f[i][j]=\max\{f[i-1][k]+b[i]-\left| a[i]-j \right|\}</script>f[i][j]=\max\{f[i-1][k]+b[i]-\left| a[i]-j \right|\} ,同时 k 能走到 j 点(即定长区间的最值)。

P2569 [SCOI2010] 股票交易:

转移多一点的时候只需要去先写朴素的方程,然后优化。

注意,尽量使用数组代替deque,因为这个东西很慢(虽然有些题实测差距不大)。

算法学习笔记【8】| 单调队列优化DP的更多相关文章

  1. 「学习笔记」单调队列优化dp

    目录 算法 例题 最大子段和 题意 思路 代码 修剪草坪 题意 思路 代码 瑰丽华尔兹 题意 思路 代码 股票交易 题意 思路 代码 算法 使用单调队列优化dp 废话 对与一些dp的转移方程,我们可以 ...

  2. bzoj1499: [NOI2005]瑰丽华尔兹&&codevs1748 单调队列优化dp

    这道题 网上题解还是很多很好的 强烈推荐黄学长 码风真的好看 神犇传送门 学习学习 算是道单调队列优化dp的裸题吧 #include<cstdio> #include<cstring ...

  3. 【笔记篇】单调队列优化dp学习笔记&&luogu2569_bzoj1855股票交♂易

    DP颂 DP之神 圣洁美丽 算法光芒照大地 我们怀着 崇高敬意 跪倒在DP神殿里 你的复杂 能让蒟蒻 试图入门却放弃 在你光辉 照耀下面 AC真心不容易 dp大概是最经久不衰 亘古不化的算法了吧. 而 ...

  4. 算法笔记--单调队列优化dp

    单调队列:队列中元素单调递增或递减,可以用双端队列实现(deque),队列的前面和后面都可以入队出队. 单调队列优化dp: 问题引入: dp[i] = min( a[j] ) ,i-m < j ...

  5. 【学习笔记】动态规划—斜率优化DP(超详细)

    [学习笔记]动态规划-斜率优化DP(超详细) [前言] 第一次写这么长的文章. 写完后感觉对斜优的理解又加深了一些. 斜优通常与决策单调性同时出现.可以说决策单调性是斜率优化的前提. 斜率优化 \(D ...

  6. Parade(单调队列优化dp)

    题目连接:http://acm.hdu.edu.cn/showproblem.php?pid=2490 Parade Time Limit: 4000/2000 MS (Java/Others)    ...

  7. 2018.09.10 bzoj1499: [NOI2005]瑰丽华尔兹(单调队列优化dp)

    传送门 单调队列优化dp好题. 这题其实很简单. 我们很容易想到一个O(T∗n∗m)" role="presentation" style="position: ...

  8. 1855: [Scoi2010]股票交易[单调队列优化DP]

    1855: [Scoi2010]股票交易 Time Limit: 5 Sec  Memory Limit: 64 MBSubmit: 1083  Solved: 519[Submit][Status] ...

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

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

  10. bzoj1855: [Scoi2010]股票交易--单调队列优化DP

    单调队列优化DP的模板题 不难列出DP方程: 对于买入的情况 由于dp[i][j]=max{dp[i-w-1][k]+k*Ap[i]-j*Ap[i]} AP[i]*j是固定的,在队列中维护dp[i-w ...

随机推荐

  1. 【Android逆向】破解看雪9月算法破解第一题

    1. 安装apk到手机 2. 随意输入账号和密码,点击register,报错crackme1:ERROR 3. 将apk拖入到jadx中进行观察 public native String regist ...

  2. 案例分享:Qt激光加工焊接设备信息化软件研发(西门子PLC,mysql数据库,用户权限控制,界面设计,参数定制,播放器,二维图,rgv小车,期限控制,参数调试等)

    需求   1.键鼠控制,承担ui界面设计,布局兼容分辨率1024x768 ~ 1920x1080.  2.权限控制:三种权限,分为管理员(可以定制模块界面,修改产品名称等定制化软件和其他权限,同时具备 ...

  3. python中动态生成类type的用法

    示例:正常创建类 class Person(object): def __init__(self): self.name = name self.age = age p = Person(" ...

  4. 【Azure 应用服务】App Service for Container中配置与ACR(Azure Container Registry)的RABC权限

    问题描述 在使用App Service for container时,在从ACR(Azure Container Registry)中获取应用的镜像时,需要使用对应的权限.默认情况为在ACR中启用Ad ...

  5. 文心一言 VS 讯飞星火 VS chatgpt (205)-- 算法导论15.4 1题

    一.求〈1,0,0,1,0,1,0,1〉和〈0,1,0,1,1,0,1,1,0〉的一个LCS.需要写代码的时候,请用go语言. 文心一言,代码正常运行: 在Go语言中,求两个序列的最长公共子序列(Lo ...

  6. [C++/QT] 获取进程完整路径

    气哭我了,我不就获取一下进程路径嘛,,,绕了好大一圈 主要是用到了GetModuleFileNameEx() 函数 食用方式如下 HANDLE hProcess = OpenProcess(PROCE ...

  7. SpringCloud Sentinel使用

    1. 简介 Sentinel 是面向分布式服务架构的流量控制组件,主要以流量为切入点,从限流.流量整形.熔断降级.系统负载保护.热点防护等多个维度来帮助开发者保障微服务的稳定性.替换原先Hystrix ...

  8. HW学习笔记

    栈库分离方法注意事项: 所有用户输入数据需要进行分离过滤,不能遗漏.选择安全的过滤函数 如 mysql_real_escape_string(),避免过滤不严格导致注入 SQL查询模板需要设计安全,米 ...

  9. 在Linux下开启指定端口号

    1.查看某个端口是否已开启,如果提示no表示未开启 #8888表示要查询的端口号firewall-cmd --query-port=8888/tcp 2.永久开启端口号,提示 success 表示成功 ...

  10. C#泛型的类型参数约束

    常用约束 约束告知编译器类型参数必须具备的功能. 在没有任何约束的情况下,类型参数可以是任何类型. 编译器只能假定 System.Object 的成员,它是任何 .NET 类型的最终基类. 如果客户端 ...