算法学习笔记【8】| 单调队列优化DP
单调队列:就是滑动窗口,可以求出定长 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的更多相关文章
- 「学习笔记」单调队列优化dp
目录 算法 例题 最大子段和 题意 思路 代码 修剪草坪 题意 思路 代码 瑰丽华尔兹 题意 思路 代码 股票交易 题意 思路 代码 算法 使用单调队列优化dp 废话 对与一些dp的转移方程,我们可以 ...
- bzoj1499: [NOI2005]瑰丽华尔兹&&codevs1748 单调队列优化dp
这道题 网上题解还是很多很好的 强烈推荐黄学长 码风真的好看 神犇传送门 学习学习 算是道单调队列优化dp的裸题吧 #include<cstdio> #include<cstring ...
- 【笔记篇】单调队列优化dp学习笔记&&luogu2569_bzoj1855股票交♂易
DP颂 DP之神 圣洁美丽 算法光芒照大地 我们怀着 崇高敬意 跪倒在DP神殿里 你的复杂 能让蒟蒻 试图入门却放弃 在你光辉 照耀下面 AC真心不容易 dp大概是最经久不衰 亘古不化的算法了吧. 而 ...
- 算法笔记--单调队列优化dp
单调队列:队列中元素单调递增或递减,可以用双端队列实现(deque),队列的前面和后面都可以入队出队. 单调队列优化dp: 问题引入: dp[i] = min( a[j] ) ,i-m < j ...
- 【学习笔记】动态规划—斜率优化DP(超详细)
[学习笔记]动态规划-斜率优化DP(超详细) [前言] 第一次写这么长的文章. 写完后感觉对斜优的理解又加深了一些. 斜优通常与决策单调性同时出现.可以说决策单调性是斜率优化的前提. 斜率优化 \(D ...
- Parade(单调队列优化dp)
题目连接:http://acm.hdu.edu.cn/showproblem.php?pid=2490 Parade Time Limit: 4000/2000 MS (Java/Others) ...
- 2018.09.10 bzoj1499: [NOI2005]瑰丽华尔兹(单调队列优化dp)
传送门 单调队列优化dp好题. 这题其实很简单. 我们很容易想到一个O(T∗n∗m)" role="presentation" style="position: ...
- 1855: [Scoi2010]股票交易[单调队列优化DP]
1855: [Scoi2010]股票交易 Time Limit: 5 Sec Memory Limit: 64 MBSubmit: 1083 Solved: 519[Submit][Status] ...
- 单调队列优化DP,多重背包
单调队列优化DP:http://www.cnblogs.com/ka200812/archive/2012/07/11/2585950.html 单调队列优化多重背包:http://blog.csdn ...
- 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 ...
随机推荐
- 谁说docker-compose不能水平扩展容器、服务多实例?
❝ 虽说我已经从docker-compose走上了docker swarm的邪门歪道,目前被迫走在k8s这条康庄大道, 但是我还是喜欢docker-compose简洁有效的部署方式. ❞ 曾其何时 d ...
- 获取Linux mac地址(centos与ubuntu通用)
ip -a addr| grep link/ether | awk '{print $2}'| head -n 1 获取Linux mac地址(centos与ubuntu通用)
- windbg 学习
常用的 windbg 命令 .ecxr 用来切换到异常发生时的上下文,主要用在分析静态 dump 文件的时候.当我们使用 .reload 命令去强制加载库的 pdb 文件后,需要执行 .ecxr 命令 ...
- 【LeetCode动态规划#01】动规入门:求斐波那契数 + 爬楼梯 + 最小代价爬楼梯(熟悉解题方法论)
斐波那契数 力扣题目链接(opens new window) 斐波那契数,通常用 F(n) 表示,形成的序列称为 斐波那契数列 .该数列由 0 和 1 开始,后面的每一项数字都是前面两项数字的和.也就 ...
- 记一次 .NET某设备监控自动化系统 CPU爆高分析
一:背景 1. 讲故事 先说一下题外话,一个监控别人系统运行状态的程序,结果自己出问题了,有时候想一想还是挺讽刺的,哈哈,开个玩笑,我们回到正题,前些天有位朋友找到我,说他们的系统会偶发性CPU爆高, ...
- 使用 ASP.NET Core MVC 创建 Web API 系列文章目录
使用 ASP.NET Core MVC 创建 Web API(一) 使用 ASP.NET Core MVC 创建 Web API(二) 使用 ASP.NET Core MVC 创建 Web API(三 ...
- 图片动态操作,利用SeekBar控制属性示例,适配屏幕解决方案
需求为,让图片适配屏幕大小,并且可以用一个滑块来控制图片的旋转,用一个滑块来控制图片大小,核心语法思路,控制图片的大小, 核心语法为:mImageView.setLayoutParams(new Li ...
- 摆脱鼠标系列 - 用git命令提交代码
需求 最近开始改变用鼠标的习惯,之前一直是用鼠标点击vscode,点击提交 现在不用鼠标,改用命令行,命令很简单,主要是习惯的改变 实现 vscode环境 ctrl + ` 快捷键打开命令行 git ...
- .NET集成DeveloperSharp实现强大的AOP
(适用于.NET/.NET Core/.NET Framework)[目录]0.前言1.第一个AOP程序2.Aspect横切面编程3.一个横切面程序拦截多个主程序4.多个横切面程序拦截一个主程序5.优 ...
- 【算法】C和Python实现快速排序-三数中值划分选择主元(非随机)
一.快排基础 1.1 快排的流程 将数组A进行快速排序的基本步骤-quick_sort(A): 递归基础情况:如果A中的元素个数是1或0,则返回. 选取主元:取A中的任意一个元素v,作为主元(pivo ...