dp 小练
选一些 dp 题做一做。随便写一些总结,DP 的具体过程和实现很简略,重在逻辑链的推导。代码可以去原题解下学习。
随缘更新。未完结。
upd:开始杂题训练,停更。
再 upd:开始 whk 了,彻底停更了 /kk。
[HAOI2011] Problem a
考虑转化题意,求最多的说真话的人。
注意到如果有 \(a_i\) 个人比 \(i\) 低,有 \(b_i\) 个人比 \(i\) 高,说明 \(i\) 的成绩排名 \(\in [a_i+1,n-b_i]\)。
将区间视作一条线段,然后把 \([l,r]\) 相同的线段合并,给 \([l,r]\) 这条线段赋权。本题就转化为了最大线段带权覆盖问题。dp + std::map 可以 \(\mathcal O(n\log n)\) 地解决这个问题。
小陷阱:如果有超过 \(r-l+1\) 个人的成绩排名 \(\in [l,r]\),那么 \([l,r]\) 的权值为 \(r-l+1\),dp 的时候取 min 判断一下就好了。
[CF605E] Intergalaxy Trips
厉害的题目,体现了遇到思维瓶颈时尝试筛除无用状态的思想。
设 \(f_i\) 表示 \(i\to n\) 的最小 无自环 步数。
注意到,对于边 \(u\to v\),若 \(f_v\ge f_u\),则无转移的必要,原因显然。
剩下的有效 \(v\) 都满足 \(f_v\lt f_u\),发现形似 Dijkstra,类似地推一下转移方程然后 \(\mathcal O(n^2)\) 求解即可。
[AGC024E] Sequence Growing Hard
最直接的想法是往 \(A_i\) 中加数变为 \(A_{i+1}\),但是这样会陷入绝境,无法进一步思考。
因为加数的情况太多,限制很复杂,遇到这种情况,考虑正难则反,删掉 \(A_{i+1}\) 中的数变为 \(A_i\)。
似乎这种正着做限制很强的题都可以反着做(?
然后考虑删掉 \(k\),其中 \(k\) 是连续一段相同数字的右端点,字典序变小的充要条件是 \(A_{i+1,k}\gt A_{i+1,k+1}\)。
这个限制很不错,适合 dp。
设 \(f_{i,j}\) 表示前 \(i\) 个序列,值域 \([1,j]\) 的方案数。
有:
转移方程的含义可以来 这里 找。
然后预处理一下就可以 \(\mathcal O(n^3)\) 了。
[AGC040E] Prefix Suffix Addition
一开始想直接把序列差分,属于是属于是了。
注意到加数不好搞,我们换成减数,方便思考。
然后你会发现这个前后缀是假的,我们可以任意操作一个子区间。
不太自然的一步:简化问题,考虑只有一个操作的时候怎么办,不妨设其为单调不降。
常见的思考模式:将原序列视作若干段单调不降区间,然后发现最小操作次数就是单调不降区间数,可以用贪心得出。
单调不升时同理。
对于一个序列,肯定有一部分是单调不降操作处理,另一部分使用单调不升,由此发现,我们可以把 \(a_i\) 拆成 \(x_i,y_i(x_i+y_i=a_i)\),对 \(x\) 序列用单调不降,\(y\) 序列单调不升。
这一步感觉比较神仙。关键在于两个操作只和数的大小有关,彼此互不影响。
考虑 DP。设 \(dp_{i,j}\) 表示 \(a_i\) 拆成 \(\left \langle j,a_i-j\right \rangle\) 的最小操作次数。
转移方程:
然后发现,\(dp_{i,\dots}\) 至多有 \(3\) 种取值,我们只需要取到每个值得最小的 \(j\) 值。
每次根据 \(a_i-a_{i-1}\) 的正负进行转移即可。
[HNOI2012] 集合选数
学过 MO,发现这个东西直接做除了枚举别无他法。如果考虑图论计数会比较谔谔。
考虑一步神仙转化:构造一个和原命题等价的命题。
发现我们可以写出这样一个矩阵:
1 2 4 8 16 32 ...
3 6 12 24 48 96 ...
9 18 36 72 ...
27 ...
原命题等价于,在这个矩阵中选若干数,且互不相邻的方案数。容易发现两者等价。但是正着构造确实难。
由于一行至多 \(\log n\) 个数,直接状压 DP 计数即可。时间复杂度 \(\mathcal O(\) 能过 \()\)。
[AGC002F] Leftmost Ball
一个序列合法,当且仅当任意一个前缀白球数量都不低于其它球的颜色种类,并且总共 \(n\) 个白球,每种颜色 \(k-1\) 个。
直接做的上限感觉也就到 \(\mathcal O(n^2k^2)\),而且基本没法优化。
考虑换一种思路,把一种颜色的球一次性放完,为了去重,我们钦定它放在从左往右第一个合法位置。
设 \(dp(i,j)(j\le i)\) 表示放了 \(i\) 个白球和 \(j\) 种其它颜色的球的方案数。
初始状态:\(dp(i,0)=1\)。
转移方程:
-
放白球:\(dp(i,j)\gets dp(i-1,j)\)。
-
放新颜色:钦定一个在最前面,剩下的随便放,即 \(dp(i,j)\gets dp(i,j-1)\times (n-j+1)\times \binom{n\times k-(j-1)\times (k-1)-i-1}{k-2}\)。
答案 \(dp(n,n)\),特判 \(k=1\)。
[CF840C] On the Beach
首先发现若 \(a\times b,b\times c\) 均为完全平方数,则 \(a\times c\) 也为完全平方数。也就是说不能相邻的数可以合并处理。
很难理解为什么后面我都会却卡在了这么小丑的一步。
考虑容斥原理,算有不合法相邻的方案数。
经典 dp 模型,先考虑一段:设 \(g(i)\) 表示一段中有 \(i\) 对不合法相邻的方案数,直接算一下即可。
段与段之间可以加法卷积,类似树形背包,时间复杂度 \(\mathcal O(n^2)\),分治 FFT 似乎可以 \(\mathcal O(n\log n)\),不过这辈子都不会去学 FFT。

浙公网安备 33010602011771号