DP Pack
之前没想着要放上来的,但是为了方便查看还是放上来吧。
现在时间是省选 Day 0。
P7154
需要按照大小匹配的问题不妨转化成括号序列。对于所有的奶牛和牛棚排序,位置相同奶牛在前。
把所有牛棚看作是右括号,奶牛看作左括号,然后进行括号匹配。最后对于所有“失配”的括号必须满足失配的最左侧的左括号在失配的最右侧的有括号的右边。
设
- 将
放到带匹配的当中, - 将
设为不被匹配的,
- 将
匹配之前的一个左括号, - 将 这时候之前一定要是没有过未被匹配的左括号
答案即为
整体的思路感觉是清晰而且自然的。
CF1188 C
比较神奇的观察性质(之前感觉都没有碰到过太多这种套路)
注意到一点,如果选择一个长度为
这个东西随着
设
这个东西显然可以用双指针 + 前缀和优化一下做到
LOJ 3575
先看看哪个好做,显然是尽量多匹配的好做(因为这样就可以忽略一定要是一个完全匹配的条件)。
这个比较容易,设
- 下一个
不匹配 - 下一个
不匹配 - 下一个
可以匹配,
可以这样转移的原因是我们发现一定不会交叉转移,即不会出现
接下来考虑尽量少匹配,从比较简单考虑开始,我们可以想到一个
下一步就是大部分进阶难度的 dp 题难点,就是对于状态的优化,前两个维度优化不太行,思考一下最后一维是不是可以优化。观察一下限制,我们比较在意的是没有匹配到的种类是什么,记录
考虑转移,有三个比较显然的转移(注意:这里的
- 下一个第一种不匹配,那么目前一定要是第一种没有被匹配
- 下一个第二种不匹配,那么目前一定要是第二种没有被匹配
- 下一对匹配
最后考虑切换状态,发现不能简单地从
注意到后面这个东西是可以预处理的,也就是可以做到
还是有不少思维含量的题目。
CF1178F2
来点区间 dp。
发现“每次染色区间之前不能有相同颜色”这个限制是相当严格的,也就是说我们染色了一段区间
考虑设
因为我们是按照顺序染色,我们找到这个区间最小出现的数字(颜色),找到其最左和最右的位置,令值
首先
我们只考虑左边,这时候还会发分成两段,一段是
总复杂度
这样就成功把复杂度降到
LOJ 3569
这个有意思的套路居然第二次遇到了。
说实话对于这个套路感觉理解地还不是很透彻,但是又开始逐渐理解了。
这种在一个数轴上面填数字的题,直接维护坐标是非常不可做的,但是我们考虑维护形成了多少个联通块,或者说多少个连续段,以及总连续段的长度。连续段的定义可以是,这几个磁铁合成一块了,之后在他们中间插任何磁铁了。
设
- 这个点新开一个连续段
。新开一个位置可以在任何两个连续段之间开,或者是头尾,即有 种选择。之后因为只是一个点,连续段总长度只会 。 - 这个点合并到之前一个连续段的左边或者是右边
每个连续段都有两边可以合并,合并之后由于要算上这个磁铁的半径,因此总长度 。 - 这个点连接两个连续段
和上一个基本是一样的理解。
这个东西有点难理解,大概可以认为,我们先不考虑两个段之间相互吸引的情况,但是当我们合并的时候(因为答案最后肯定要合并成一个连续段),我们就会考虑到这种情况了。
最后,我们肯定只能是一个连续段,而且加入我们的长度是
回去看一眼 ABC313Ex,这个其实是一个道理,看看现在能不能够更好理解了。
非常好,故题重做理解了。
P8352
来点 dp 套 dp。其实这个东西没有那么恐怖。
这个题如果每个点是确定的就是一个简单的树形 dp,设
这个时候我的考虑是设
其实这里就已经就是 dp 套 dp 的形式了,外面是一个大的背包,里面是一个小的 dp 转移。
但是这个东西并不能通过,因为其状态就已经是
这题关键的点在如何化简状态,其实所有 dp 都在于此,观察一下我们需要的东西有什么,我们需要的是
那么下一步就呼之欲出了,记录
这也是一种比较经典的化
由于这种复杂度不是最优的复杂度,因此需要一些适当的卡常,如 longlong
等。
CF932 F
这个题就偏向板子了,但是写一下还是有不少收益的。
转移的式子是好推的,即
但是对于每一个节点不能直接重新建一个李超,不然会爆炸,但是一个点是吸取所有子几点的最优值,也就是说可以直接线段树合并。有两个细节:
- 由于
的 可能取负数,因此需要整体加一个数,询问 + 计算的时候减去即可 - 李超线段合并的过程每次合并两个点需要把其中一个点的信息当作一个新的直线插入另一个线段树中,即
,这样可以做到信息的保留。
没带电脑来学校,学校刚好又在做 dp 专题,随便记一下。
P5504
做点决策单调性的东西,之前那个里面似乎没有。
感觉难点在于观察出来性质,会发现每次分割的区间会满足两个条件
- 左右端点的大小一定相等
- 选择的
这个不难证明(由于某软件突然闪退了,东西没了)。
这样就有转移,设
这个状态看起来已经非常简洁了,考虑在转移上面下功夫。
如果设
如此就可以维护一个单调栈,通过二分判断什么时候会比上一个栈顶劣。
具体操作还是有一点细节的,对于单调栈的操作应该如下:
- 如果栈顶的元素能够持续贡献到
,之后就会被上一个元素覆盖,再如果当前元素相对于栈顶的元素能够贡献到 。如果 那么栈顶的元素应该被弹出。因为这个元素贡献的过程已经可以完全包括栈顶元素贡献的过程了 - 将当前元素塞入栈中
- 考虑栈顶的元素是否是比上一个元素优,这里针对的是当前的位置,也就是栈顶元素能不能贡献到这个位置
- 进行 dp 转移
P3592
区间 dp, 感觉不算太难,要有胆量。
首先显然的每个位置一定是
直接暴力区间 dp 设
其中的
StringWeight
比较精巧的一道题。
对于一个轻的字符串,显然如果长度小于26那就是每一个字符出现一次,如果大于26,每一个字符一定是出现在连续的一段当中的。
对于题目要求的东西,我们其实只关心每一个字符的起始节点和终止节点。
设一个四元组:
-
:只出现在当前的字符串中 -
:第一次出现在总串中(显然后面还要再次在别的字串中出现过) -
:最后一次出现在总串中,即 的闭合 -
:路过,即在 中间。
对于一个四元组,我们发现可以
CF868E
首先显然一定有解,实在不行警察硬着头皮一个小偷一个小偷抓,因为是在一棵树上一定能够抓到。些简单的观察发现,小偷苟在叶子节点一定是不错的选择,这样可以甩警察尽可能远。
反过来想,警察每次抓到小偷一定是在一个叶子节点。这时候可能还会剩下一些小偷,由于警察是在一个叶子节点,那么剩下小偷可以趁这个时间随意调整位置,让警察再次出发的时候消耗时间最多。因为可以随意移动,我们不妨设
状态很理想,考虑如何转移。假设剩下的每个叶子节点的小偷数量已经确定了,为
最后统计答案,由于起始的位置不一定是叶子,但是这影响并不大,因为这个条件对于小偷的唯一限制就是一个小偷不能跑出其所在的子树。那么开始的时候记录一下每一个子树中小偷总数然后再贪心即可。
复杂度
CF726F
发现
设
其中只需要保证
P5336
感觉这个区间 dp 挺神秘的。
首先是区间 dp 显然的。不妨先设
再思考对于
左边直接全部扔掉并付出代价,右边余下满足最大最小值的条件 同上 也是一样的,这时候是两个部分拼起来的。
LOJ 6240 + CF235 D
好题!还是很有趣的题,虽然感觉其实算不上 dp。
先看后面这个题,关键在与拆贡献。注意到每个点都会被当作点分治的中心,也就是需要统计每个点作为点分治中心时所属联通块大小的期望值。
更进一步,其实是需要计算有多少个点和这个点联通。这时候我们考虑暴力枚举点分治中心
先思考在树上的时候怎么计算
那么基环树呢?如果两个点只有一条路径相互到达就是平凡的,和上面计算方法一样。否则,设一种方案的长度是
进一步到仙人掌上。这时候
与基环树的思路类似,我们选定一些连接这两个点的路径,并设其并集为
之后就简单了,设 枚举起始点后,设
AGC002F
学校的 dp 专题,顺手来写一下。
(现在才发现我的标题有时候是 H2 有时候是 H3,难绷)
优化状态题,显然不可能记录每一个球放了几种,这样还需要带着下标(因为每一次只放一个)是无法接受的,那么考虑每一次一次性放完一整个颜色,思路就变得清晰起来了。
首先要确定白色球的情况,会发现白色球和其他的球是不会相互影响的,唯一的限制就是对于任何一个位置,前缀白色球的数量一定要大于出现颜色的数量。不妨设
转移不难,唯一要注意的是,我们需要钦定当前放的球一定要在没有放置位置的第一个位置,这也是比较经典的套路了,为的就是避免算重。
首先一定有
注意这种计算方式需要特判
感觉评分高了。
CF1775F
对于
对于
那么现在变成计算,令
预处理
注意到
CF1602F
感觉这种需要一点性质的 dp 还是不太行啊。
本人第一反应是找到最大数然后推,其实感觉方向也没有太离谱,但是就不是很优秀。然后就有点卡住了。
正确姿势是注意到有偏序关系即如果有
这个限制优秀在于其限制性非常强。这导致的结果是原序列变限制成必须是两个上升子序列合并出来的。而且贪心一点想,这两个上升子序列就是两个不相交的单调递增的折线。
之后就不难了,考虑
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 无需6万激活码!GitHub神秘组织3小时极速复刻Manus,手把手教你使用OpenManus搭建本
· C#/.NET/.NET Core优秀项目和框架2025年2月简报
· Manus爆火,是硬核还是营销?
· 一文读懂知识蒸馏
· 终于写完轮子一部分:tcp代理 了,记录一下