【学习笔记】线段树优化DP
dp,即动态规划中有一类很重要的优化,叫做线段树优化。本文将介绍几种常见的类型及其套路和一些例题。
前置知识:线性 dp、线段树。
被 NOIP2023 暴打之后爬来补 dp 了。
定义
为了方便理解,先声明一下本博客中的如下定义(可能有误,所以仅限于本博客,可能不能作为参考):
当前
:包括本轮待计算的 dp 值和遍历到的信息。决策
(jc):即更新 dp 值,可以理解为转移。决策点
:即某个 dp 值的转移处。(如 可以从 转移,且 为它最终取到的(即最优的)值,那么称 为决策点)决策值
:即某个 dp 值的转移值。
以最长上升子序列为例。
假设本轮要计算 当前
的 dp 值,当前
的信息。
若 决策点
,称 决策值
。
我把线段树优化 dp 决策分为「静态修改」和「动态修改」,这样分类是因为思考方式不同:前者通常可以从状态转移式子中容易的分离出决策点的贡献,而后者更多的是从当前的信息变化推出会对线段树上的决策值有何影响。
上面这段是对两种题型的总结,在做题之前看不懂很正常,我也很难描述。通过解决一些例题再回来看,自然就会明白了。
静态修改
即在线段树上的唯一修改是把某个转移完毕的 dp 状态丢到线段树上。此时后面的 dp 转移快速查询最优决策时,贡献的部分可以拆为 当前的贡献 和 决策点的贡献 ,且「决策点」部分贡献恒定不变,因此不用做修改。
CF1304F Animal Observation
Easy version
Hard version
等等,这不是能单调队列么?
但是我们的专题是线段树优化 dp(doge)
权值线段树优化 dp
此类题目的 dp 转移通常和数值的大小关系有关,以下将介绍几道权值线段树优化 DP 题。
CF597C Subsequences
给定一个
的排列 ,求 中长度为 的上升子序列个数(IS)。
, , ,答案不超过 。
首先设计 dp,
转移有
如果没有
如果令
这时候就看的很清楚了,可以把
时间复杂度
P3431 [POI2005] AUT-The Bus
(太简单所以懒得写)
CF474E Pillars
(太简单所以懒得写)
CF960F Pathwalks
首先这个东西显然和我们的 LIS 很像,于是考虑设
- 决策点的
当前的 - 决策点的
当前的
没有第一个的话可以考虑开权值线段树维护。有了第一个的话,可以考虑开
时间复杂度
动态修改
即要随着 dp 的进行来修改线段树上的决策值。此时 dp 转移方程通常有一个动态贡献,这个贡献会随着决策点的变化而变化。
这类题在初次遇到常常难以下手,不过只要会了「修改决策值」的思考方式,这种题就全都是套路不止于愣着不会做了。
另外,我是从 lsj2009 的博客里学习的这类套路,在此万分感谢!
(唔,下面的题解暂时没有补 qwq。可以先看看 lsj2009 的博客,看懂的话下面都会做了。)
CF833B The Bakery
P9871 [NOIP2023] 天天爱打卡
P1848 [USACO12OPEN] Bookshelf G
到这里的话,如果你已经理解了这种套路,类似的题可以直接根据套路秒掉。现在你可以试试把这道 USACO 的题秒掉。另外还有道一模一样(而且只有一个
本文作者:Aquizahv's Blog
本文链接:https://www.cnblogs.com/aquizahv/p/18552581
版权声明:本作品采用知识共享署名-非商业性使用-禁止演绎 2.5 中国大陆许可协议进行许可。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步