dp 小练

选一些 dp 题做一做。随便写一些总结,DP 的具体过程和实现很简略,重在逻辑链的推导。代码可以去原题解下学习。

随缘更新。未完结。

upd:开始杂题训练,停更。

再 upd:开始 whk 了,彻底停更了 /kk。

[HAOI2011] Problem a

考虑转化题意,求最多的说真话的人。

注意到如果有 ai 个人比 i 低,有 bi 个人比 i 高,说明 i 的成绩排名 [ai+1,nbi]

将区间视作一条线段,然后把 [l,r] 相同的线段合并,给 [l,r] 这条线段赋权。本题就转化为了最大线段带权覆盖问题。dp + std::map 可以 O(nlogn) 地解决这个问题。

小陷阱:如果有超过 rl+1 个人的成绩排名 [l,r],那么 [l,r] 的权值为 rl+1,dp 的时候取 min 判断一下就好了。


[CF605E] Intergalaxy Trips

厉害的题目,体现了遇到思维瓶颈时尝试筛除无用状态的思想。

fi 表示 in 的最小 无自环 步数。

注意到,对于边 uv,若 fvfu,则无转移的必要,原因显然。

剩下的有效 v 都满足 fv<fu,发现形似 Dijkstra,类似地推一下转移方程然后 O(n2) 求解即可。


[AGC024E] Sequence Growing Hard

最直接的想法是往 Ai 中加数变为 Ai+1,但是这样会陷入绝境,无法进一步思考。

因为加数的情况太多,限制很复杂,遇到这种情况,考虑正难则反,删掉 Ai+1 中的数变为 Ai

似乎这种正着做限制很强的题都可以反着做(?

然后考虑删掉 k,其中 k 是连续一段相同数字的右端点,字典序变小的充要条件是 Ai+1,k>Ai+1,k+1

这个限制很不错,适合 dp。

fi,j 表示前 i 个序列,值域 [1,j] 的方案数。

有:

fi,j=k=1ip=ik+1i(p1ik)×fik,j×fk1,j1

转移方程的含义可以来 这里 找。

然后预处理一下就可以 O(n3) 了。


[AGC040E] Prefix Suffix Addition

一开始想直接把序列差分,属于是属于是了。

注意到加数不好搞,我们换成减数,方便思考。

然后你会发现这个前后缀是假的,我们可以任意操作一个子区间。

不太自然的一步:简化问题,考虑只有一个操作的时候怎么办,不妨设其为单调不降。

常见的思考模式:将原序列视作若干段单调不降区间,然后发现最小操作次数就是单调不降区间数,可以用贪心得出。

单调不升时同理。

对于一个序列,肯定有一部分是单调不降操作处理,另一部分使用单调不升,由此发现,我们可以把 ai 拆成 xi,yi(xi+yi=ai),对 x 序列用单调不降,y 序列单调不升。

这一步感觉比较神仙。关键在于两个操作只和数的大小有关,彼此互不影响。

考虑 DP。设 dpi,j 表示 ai 拆成 j,aij 的最小操作次数。

转移方程:

dpi,j=mink[0,ai1]{dpi1,k+[j<k]+[j<k+aiai1]}

然后发现,dpi, 至多有 3 种取值,我们只需要取到每个值得最小的 j 值。

每次根据 aiai1 的正负进行转移即可。


[HNOI2012] 集合选数

学过 MO,发现这个东西直接做除了枚举别无他法。如果考虑图论计数会比较谔谔。

考虑一步神仙转化:构造一个和原命题等价的命题

发现我们可以写出这样一个矩阵:

1 2 4 8 16 32 ...
3 6 12 24 48 96 ...
9 18 36 72 ...
27 ...

原命题等价于,在这个矩阵中选若干数,且互不相邻的方案数。容易发现两者等价。但是正着构造确实难。

由于一行至多 logn 个数,直接状压 DP 计数即可。时间复杂度 O( 能过 )


[AGC002F] Leftmost Ball

一个序列合法,当且仅当任意一个前缀白球数量都不低于其它球的颜色种类,并且总共 n 个白球,每种颜色 k1 个。

直接做的上限感觉也就到 O(n2k2),而且基本没法优化。

考虑换一种思路,把一种颜色的球一次性放完,为了去重,我们钦定它放在从左往右第一个合法位置。

dp(i,j)(ji) 表示放了 i 个白球和 j 种其它颜色的球的方案数。

初始状态:dp(i,0)=1

转移方程:

  • 放白球:dp(i,j)dp(i1,j)

  • 放新颜色:钦定一个在最前面,剩下的随便放,即 dp(i,j)dp(i,j1)×(nj+1)×(n×k(j1)×(k1)i1k2)

答案 dp(n,n),特判 k=1


[CF840C] On the Beach

首先发现若 a×b,b×c 均为完全平方数,则 a×c 也为完全平方数。也就是说不能相邻的数可以合并处理。

很难理解为什么后面我都会却卡在了这么小丑的一步。

考虑容斥原理,算有不合法相邻的方案数。

经典 dp 模型,先考虑一段:设 g(i) 表示一段中有 i 对不合法相邻的方案数,直接算一下即可。

段与段之间可以加法卷积,类似树形背包,时间复杂度 O(n2),分治 FFT 似乎可以 O(nlogn),不过这辈子都不会去学 FFT。

posted @   Modirant  阅读(30)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 百万级群聊的设计实践
· 永远不要相信用户的输入:从 SQL 注入攻防看输入验证的重要性
· 全网最简单!3分钟用满血DeepSeek R1开发一款AI智能客服,零代码轻松接入微信、公众号、小程
· .NET 10 首个预览版发布,跨平台开发与性能全面提升
· 《HelloGitHub》第 107 期
点击右上角即可分享
微信分享提示