单调队列优化dp

如果一个选手比你小还比你强,你就可以退役了。

有人高一了,学会了单调队列优化dp,这下是真被单调队列了😅

能用单调队列优化dp的问题一般都是滑动窗口的形式:写出朴素 dp 转移式后发现本质上是在一段长度固定且连续的单调区间中找最值(单调区间指区间移动方向是单调增减的),这个时候就能考虑单调队列优化,将复杂度降一个 O(n)。线段树能做的操作多一些,优先队列只能处理 dp[j] 转移过来的值与 i 无关的情况,但处理的区间可以不连续,线段树也是。

做题思路的话就是一定要先写出朴素dp转移式,然后观察能不能转化成类似滑动窗口的形式。dp优化题都是这样的,但是如果你发现转移式根本拆不开,根本想不到怎么优化,可以考虑重新从优化的角度设一个新的能被优化的状态。

给一个单调队列优化的模板,理解上采用了经典的选手退役模型:

h=1,t=0;
for(int i=1;i<=n;++i){
    while(h<=t&&i-q[h]>k) ++h; //老年选手退役
    if(h<=t) dp[i]=...; //最强选手进省队
    while(h<=t&&dp[q[t]]....) --t; //被新生单调队列的学长退役
    q[++t]=i; //新选手加入OI队列
}

P3572 [POI2014] PTA-Little Bird

这个题比较毒,只能单调队列优化dp不能线段树维护。朴素转移很简单:dp[i]=maxj=iki1dp[j]+[aiaj]。复杂度要求 O(qn),考虑单调队列优化。板子题不过多赘述。

P2569 [SCOI2010] 股票交易

不难的题,还是先写出朴素转移,状态是好设的:令 dp[i][j] 表示第 i 天有 j 支股票的最大收益,刷表法考虑第 i 天有四种转移的情况:

1. 啥都不干,直接从前一天转移来 dp[i][j]=dp[i1][j]

2. 第一次买股票,收益为 dp[i][j]=j×APi,j[0,ASi]

3. 枚举在第 iw1 天有 k 支股票,今天买到 j 支,dp[i][j]=maxk=jASij1(dp[iw1][k](jk)×APi)

4. 枚举在第 iw1 天有 k 支股票,今天卖到 j 支,dp[i][j]=maxk=j+1j+BSi(dp[iw1][k]+(kj)×BPi)

复杂度瓶颈在于枚举 k 的朴素转移,总复杂度 O(nP2)。容易发现,在固定了 i,j 之后,第三种和第四种转移就是在长度固定的连续单调区间中找最值,显然能单调队列优化,能优化到 O(nP)。注意单调队列初始的指针赋为 h=1,t=0,这样才能让第一个元素正确。

P2034 选择数字

发现以前用优先队列过了一道单调队列优化dp的题,看来是自己做的了。

朴素转移很简单,令 dp[i] 表示前 i 个数不选 i 时的答案:dp[i]=maxj=iki(sum[i1]sum[j1]+dp[j1]),答案便是 dp[n+1]

单调队列是显然的,但我用的优先队列。考虑到转移过来的 j 的范围只和 i 有关且是单调的,于是考虑在优先队列里塞 pair(-sum[j-1]+dp[j-1],1),前者是只和 j 相关的贡献,后者是编号。当枚举到 i 时取堆顶元素就行了,如果无法从其转移就不断弹出。

P2254 [NOI2005] 瑰丽华尔兹

朴素dp:令 dp[i][x][y] 表示 i 时刻在 (x,y) 的答案,初始是 0 时刻,转移很容易。

这个状态是很难优化的,i(x,y) 都不好拆开维护。考虑重设状态 dp[i][x][y] 表示第 i 个时间段在 (x,y) 时的答案。转移是 dp[i][x][y]=max(dp[i1][x][y]+dis),这个 dis 对不同的方向需要分讨。以当前时间段的方向向南为例,设这段时间长 len,那么具体的转移就是 dp[i][x][y]=maxp=xlenx(dp[i1][p][y]+xp),可以考虑将定值搬到 max 外,写成: dp[i][x][y]=maxp=xlenx(dp[i1][p][y]p)+x。这个时候已经可以发现,转移的范围就是一段长为 len 的连续的区间,可以用单调队列优化掉枚举 p 的过程。空间的话直接开是开得下的,也可以滚动数组优化掉 i 这一维。注意四个方向的转移顺序和转移式都不一样。

P3800 Power收集

我傻。直接就是滑动窗口,但是 j 在窗口的正中间。试过不能正反两次单调队列,于是考虑在开始对每一行开始dp前就把 1T 的元素入队,然后不断加入 j+T 的元素,在加入元素的时候就顺便把该退役的元素给弹出了。

posted @   和蜀玩  阅读(25)  评论(3编辑  收藏  举报
相关博文:
阅读排行:
· 物流快递公司核心技术能力-地址解析分单基础技术分享
· 单线程的Redis速度为什么快?
· 展开说说关于C#中ORM框架的用法!
· Pantheons:用 TypeScript 打造主流大模型对话的一站式集成库
· SQL Server 2025 AI相关能力初探

阅读目录(Content)

此页目录为空

点击右上角即可分享
微信分享提示