CF DP 2300~3000 板刷
我把荆棘当作铺满鲜花的原野,人间便没有什么能将我折磨。
他们说,击败我即是终结,而我必将归来将之改写。
加入省选训练里面了,我对 BZ 的题彻底失望了。
1. CF1421E Swedish Heros
首先有一个
考虑通过对小数据打表找规律。
主要是去观察序列上哪些点最终符号为
惊讶的发现
直接暴力 DP,
暴力转移,复杂度
2. CF1174E Ehab and the Expected GCD Problem
首先考虑最优排列
定义
考虑将
- 定义
表示前 个数的最大公因数为 的方案数。下面考虑转移。 - 如果
位的最大公因数就已经是 ,那么转移就是 。比较好理解,因为这一位只需要是 的倍数且与前面不重即可。 - 如果
位的最大公因数是 ,到了这一位才衰减为 ,这一位显然是 的倍数,却不是 的倍数,转移即
初始值即
对于
3. CF115D Unambiguous Arithmetic Expression
我是一个拼命优化,交了
当然,这个暴力
一段数字显然可以看成一个数字,缩下来之后,考虑一下左右括号的组成。
首先,右括号必然出现在数字后面,显然你符号后面是不可能出现右括号的。并且数字后面的右括号可以是任意个,只要和前面的左括号能匹配上。
其次,左括号也必然不会出现在数字后面,你总不可能数字和符号/数字之间凭空出现一个左括号。故左括号必然出现在符号后面,且每个符号后面应该必须出现刚好一个左括号,不多不少。
我们按照上面两种限制去填左右括号,且只需要满足最终填出来的括号刚好匹配,然后再算方案书貌似就是答案。
但是我们忽略了一种情况,就是
特判掉之后,根据上面的两条限制,我们直接 DP,定义
, 。 为数字, 。
初始值
4. CF1481E Sorting Books
以前应该是做过的,但是我为啥没有提交记录,那就再来自己做一遍。
又要看题解了,真的要哭了啊,为什么会想到去转化它呢。。。
一个很重要的转化是将最小变化数转化为
定义
- 如果我们选择改变第
位的位置,有: 。 - 如果我们选择不改变第
位的位置,那么显然我们也不会改变所有和 颜色相同的点的位置,有 - 不改变第
位的情况,其实在这种情况下,我们忽略了另外一种转移。你虽然不改变所有和 不同的颜色,但他并不意味着其他颜色必须要改,但是第二种转移并没要考虑到。假设所有和 颜色相同的位置,最左边的位置是 ,最右边的位置是 。发现对于 内的除开和 相同的所有位置,在和 颜色相同的位置都不改变的情况下,这些位置都是要改变的。但是对于 这里面的位置,其实他们改不改对我们来说并没有所谓。故在 的情况下,有 ,其中 表示和 相同的颜色的所有出现次数。 - 将三种转移取
即可。 - 答案即
。
边转移边打桶,时间复杂度应该是
5. CF316D3 PE Lesson
首先有一个比较重要的东西,就是说,我们只关心
说实话,最开始真没想到这个东东。
考虑
定义
然后考虑
假设最终的排列第
假设
先考虑插入一个
那么对于
总时空复杂度
6. CF1430G Yet Another DAG Problem
这个东西有点像分层图,每次将一个集合的
具体来说,定义
那么答案就是
考虑定义
考虑枚举
应该是比较好理解的,输出方案直接打个
此时稍微预处理一些东西,时空复杂度
可以考虑去把
此时时间复杂度
但是疑似是我写的太劣了,貌似同样的解法就我这么极限。
7. CF232E Quick Tortoise
首先这个
最开始感觉就是排序之后将
考虑离线利器
考虑按照
对于
考虑定义
每层分治暴力转移,并且采用
对于满足
对于剩下的点对,如果
然后就结束啦,时间复杂度瓶颈在于 DP 转移的
感觉难点不在 DP 上,而是你对于离线的处理。
8. CF762D Maximum path
起初是没什么思路的,但是我们回忆一下序列 DP 的常见类型,发现这个题影响序列从左向右进行 DP 的罪魁祸首是向左走这种情况。
但是向左走总感觉是在远离目标点,那能不能有些限制呢?
手玩一些小数据发现,每种路径总存在一种方案,只会最多连续向左走
定义
- 如果
并不会想左走到 ,那么就是从 直接走过来找最大值即可。 - 如果
会向左走到 ,那么就是 走过来找最大值即可。
注意一下里面两种转移的走法和细节即可。
9. CF1784D Wooden Spoon
感觉题目中的组合意义奇怪转移跟今天的考试非常像,正好我提前一天看了这道题,赢!
首先有两种考虑方法:
- 考虑自底向上,需要记录一直连败的叶子节点编号,以及当前的赢家和轮次,时空复杂度至少在
,不太能接受。 - 考虑自顶向下,只需要记录当前的赢家,且钦定他在从上到下的过程中一直失败即可,时空复杂度至少是
。
观察到只有“自顶向下”对我们来说才是有前途的。为了方便叙述,我们将题目中的编号小赢直接钦定为编号大赢,然后输出反过来就行了。
故我们定义
- 考虑顺推,即
,想一下系数是多少。发现实际上在 层 子树无论是什么方案都能赢,可以随便排列,实际上就是 ,其中 表示找出所有的 个放在 子树下的编号,将其任意排列,并且由于 可以交换,还要 。 - 发现转移系数与
无关,直接前缀和优化即可。
总时间复杂度
对于组合数系数的相关疑惑和相关代码可以参考这篇题解。
10. CF1279F New Year and Handle Change
草了,找半天给我找来一道限制为最多
首先如果没有这个限制,显然可以直接暴力 DP,从
要去掉这个限制显然是一眼
假设
时间复杂度
我不会
11. CF1144G Two Merged Sequences
神 TM
完啦,被
首先有一个比较显然的
发现这个可行性 DP 状态非常的冗余,考虑模仿最长上升子序列单
具体来说,定义
考虑如何转移:
- 先看怎么转移
。 - 如果
,显然有 。 - 如果
,显然有 。 - 将两者取
即可。 同理。然后可能需要再维护一个决策点数组来记录方案(但是这里貌似可以直接暴力向前跳没必要打数组。)
12. CF1845E Boxes and Balls
日常计数题最开始一点思路都没有。题解区怎么全都说是些经典套路啊啊啊啊啊。
又是经典的看完题解恍然大悟。
感觉正着做直接去 DP 的话是非常容易算重的,故考虑去看哪些数组
考虑将原数组
注:后面所说的
,即这样的位置个数应该相同。 。
后面有个
故有一个很智慧的 DP,即定义
转移是非常简单的,直接
有一个很套路的东西是,去计算每个位置
观察到
考虑换 DP 状态,定义
13. CF1615F LEGOndary Grandmaster
故意找了一道和上一题比较类似的。但是依然不会。
为啥我感觉一点也不类似捏。。
”我们发现将两个相邻的且相同的数取反就是直接将原数组的所有奇数的位置取反,然后每次操作看成交换相邻两个不同的数,最后看是否和目标数组的奇数位取反相等。“然后就转化成了上一个题的操作。
不是哥们,你是神仙吗,怎么看出来的啊。。什么阴间转化啊。。
然后转化成上一道 CF1845E 的操作之后,我们仍然是类似的进行 DP,但是我们发现并不需要去记录
这里由于并没有操作次数上限,所以
14. CF1221G Graph And Numbers
感觉是比较弱智的题目,但是我最开始对于折半的答案合并并没有想的太清楚,所以还得练。
首先是比较显然的容斥,答案应该就是
然后为了方便计算,先把
,随意染色,显然。 ,考虑求出图上的所有独立集,这些独立集内部的点可以都染上 ,其他点必须染上 。经典的独立集计数,观察到数据规模是 ,考虑折半搜索,合并两边的答案即可。合并的话应该就是一个简单的高维后缀和(因为有些点的限制,在左半选了,右半就必须不选,而且你可能需要求个补集什么的),这里不细讲了。时间复杂度 。 ,对于一个连通块,任意一条边两端的点权应该一样,答案就是 。( 表示连通块个数) ,显然,不过是所有的 必须构成一个独立集。 ,如果一个连通块大小 ,那么显然里面的点的点权都必须为 ,如果一个连通块是一个单独的点,那么显然既可以是 也可以是 。答案就是 。( 表示连通块大小为 个数) ,显然,对于每个连通块,如果都是一个二分图,我们才有办法使得其没有 的边权,类似一个黑白染色,在满足都是二分图的情况下,答案就是 。 ,依然是比较显然的,就是反过来了而已。 ,显然。
华丽结束,总复杂度应该是 又是完成了 6 道题目的一天。
15. CF1743F Intersection and Union
VP 遇到的一道题,感觉挺有价值的,而且也让我认识到了一种全新的数据结构优化 DP。
首先你肯定是想到统计对于一个权值有多少种方案会出现在最终集合里面,然后加起来就可以了。
然后有一个
稍微写一下这个柿子:
观察到上述转移非常像矩阵的形式:
你考虑对于每个
时间复杂度
经过自己的实现,确实需要主意矩阵乘法的时候尽量用
这个旨在告诉你,对于一个二维甚至高维的 DP,你每次转移如果可以写成矩阵形式,并且是一整段一整段的乘上这个转移矩阵,那么你就可以直接把 DP 放进线段树上,然后区间乘矩阵。
16. CF1767E Algebra Flash
题意是比较清楚的。
而你要从起点到达终点的一个充分必要条件是:
- 必须选择起点和终点。
- 相邻两个点必须选择一个点。
故你考虑对于起点和终点的颜色连一个自环,然后将相邻两个点分别对应的颜色连一条边。
故这个题就转化成了一个一般图最小带权点覆盖的问题。
而我们知道最小带权点覆盖
故我们只需要知道这个图的最大带权独立集是什么。
首先有一个很
另外,我们定义点
转移的话本质上我们只需要考虑这个集合中的任意一个点就行了,为了方便我们后面的优化,考虑
显然有:
时间复杂度
但是这里
于是我们考虑一个奇技淫巧,也是这个算法的关键所在。
首先先把这个
时间复杂度我们简单的证明一下。
对于搜索的前
对于后面的
故总时间复杂度
本题代码和更多细节见此。
17. CF1739E Cleaning Robots
如此唐氏的 DP 我居然想了这么久我是不是废了。
我们先思考一下什么情况下会崩溃。
观察到对于一个脏格子
这指向我们去维护一下下一行上下两个格子的状态,即他们是否被清理。
故我们定义
你考虑直接枚举
个人认为有一篇比较好的解释。
18. CF1743E FTL
有一个比较显然的
额这个状态及其的冗余啊。而且看了样例我才知道这个充能是可以两个飞船同时充能的。
定义
先看只需要蓄力一个的暴力转移,即:
考虑怎么对于同时蓄力的进行转移。观察到你可以把两个同时打出,看作打出一个的同时另外一个正好蓄好了力,正好可以打出去。
故你考虑枚举
首先显然要满足
然后你看在这期间
时间复杂度
MD,读错题了,浪费了我一个小时。
19. CF407D Largest Submatrix 3
考试题,感觉自己的做法挺不错,搬过来。
题解非常清晰明了,这里懒得讲了,讲一下自己的巨恶心做法。
为了将这个做法优化到
说实话这个做法真的挺难有语言描述的。
首先你考虑维护一个
接着维护一个
有了
有了这三个数组之后,答案应该是非常好维护的。
我们考虑枚举这个长方形的的最上面一行,假设是第
答案应该是
感觉还是比较好理解的。至于里面的那一坨
里面唯一的难点在于
观察到
其实还有一堆细节,可以考虑直接看代码。
20. CF1988F Heartbeat
好题,以前写过题解,直接搬进来。
21. CF53E Dead Ends
显然,定义
考虑顺推,直接枚举一个不在
但是这样显然是会算重的,就是说你一课树可能会被计算多次。
手玩一下,发现对于每一个
然后就过了。。时间复杂度应该是
22. CF813D Two Melodies
好久没有自己做出来一道题了,老泪纵横啊。
定义
先考虑怎么暴力转移:
- 如果要将
自己加入第一个序列,考虑枚举 ,有 。 - 如果要将
自己加入第二个序列,考虑枚举 ,有 。
此时时间复杂度应该是
优化是非常简单的,考虑维护四个前缀
此时总时空复杂度均为
23. CF1497E2 Square-free division (hard version)
可以把这个选择
定义
考虑转移:
- 枚举
,转移就是 ,其中 表示将 看作一个字段最少需要操作多少次。 - 难点显然在于
怎么快速求。 - 这就牵扯到怎么看两个数的乘积是完全平方数了。考虑对于所有的
,找到最大的 ,满足 ,然后令 ,那么要使两个数 的乘积是平方数的充要条件就是 。(这一步可以通过质数筛求得每个数的最小质因子来完成) - 故进一步的,
其实就是 , 表示 这个区间中不同的数的个数。显然,因为每个子段只能保留互不相同的数,不然乘积就会出现完全平方数。 - 倒着枚举
,打个桶记录一下,应该就可以求出 。
此时时间复杂度应该是
考虑怎么优化:
- 观察到,
,根据定义,这个应该是比较显然的。 - 发现所有能转移的
必然满足 (这个 是题目里面输入的。) - 并且,对于
, 显然只有 种。 - 对于这
种 ,每种 的转移显然只需要找到最左边的 进行转移,正确性根据第一个性质即可得到。 - 发现此时每个
的有效转移数量最多只有 个,复杂度瓶颈在于怎么找到每种 对应的满足条件的最左边的 。 - 发现可以维护
个双指针,对应每种 当前 最左边的位置,每次从 的时候,去判断当前的指针是否合法,不合法就一直往右跳就行了,跳的中途打桶维护即可。
此时时间复杂度
24. CF1681F Unique Occurrences
首先,这个题应该可以直接暴力
貌似是一道线段树分治的基础题,咳咳,这不重要。
我们考虑一些更简单的方式,比如树形 DP。
首先先考虑这个方案是怎么来的,本质上应该是去算每一种颜色的贡献。对于每一种颜色的贡献,可以看作是把这种颜色的边删掉,然后求出剩下的连通块大小,然后对于每条删掉的边,答案加上两个端点分别对应的连通块大小的乘积。
考虑如何快速计算这个过程。。
定义一个点的点权是其到其父亲节点的点的边权。
定义
转移是比较容易的,考虑先将
考虑如何通过
感觉是比较好理解的。看不懂我在写什么的,代码应该也是能看懂的。。
25. CF1521D Nastia Plays with a Tree
额,感觉是比较简单的树形
转化一下题意,就是将一棵树删成若干条链的操作次数。
定义
转移应该是比较简单的,如下:
void dfs(int x, int last)
{
int sum[3] = {0, 0, 0}, minn = INT_MAX, min2 = INT_MAX, son = 0;
for (int i = fst[x]; i; i = arr[i].nxt)
{
int j = arr[i].tar;
if(j == last) continue;
dfs(j, x);
dp[x][0] += dp[j][1] + 1;
if(dp[j][0] - dp[j][1] < minn) min2 = minn, minn = dp[j][0] - dp[j][1];
else if(dp[j][0] - dp[j][1] < min2) min2 = dp[j][0] - dp[j][1];
sum[0] += dp[j][0] + 1, sum[1] += dp[j][1] + 1;
++son;
}
if(son) dp[x][0] = min(dp[x][0], sum[1] + minn - 1);
if(son >= 2) dp[x][1] = sum[1] + min2 + minn - 2;
dp[x][1] = min(dp[x][0], dp[x][1]);
}
然后输出方案就可以恶心到吐了。。
26. CF1442E Black, White and Grey Tree
非常的妙啊,一道循序渐进的题。
先考虑链的情况,假设这个链没有灰色,你考虑将一段相同的黑色或者白色合并在一起,那么这条链就变成了黑白相间的,假设长度是
感觉是比较好理解的。
然后考虑迁移到一棵树上。如果这棵树只有黑白,那么显然就是这棵树对应的链就是在黑白相同合并之后的直径。
而你现在就是要将灰色染成黑白然后求合并之后的直径的最小值。
考虑 DP,类似求树的直径,设
类似直径的转移。比较容易。
答案就是
27. CF512D Fox And Travelling
首先,在环中的点一定不会被遍历。
用类似拓扑排序的过程可以把环上的点全部扔掉,剩下的点会构成若干个有根树和无根树,其中有根树的根是树中唯一与环中的点相连的点。
显然对于有根树,直接跑树上背包。
对于无根树,以树中每个点为根做一次有根树的树上背包,这样会发现每种选择
然后合并即可。
28. CF111D Petya and Coloring
这题有个 DP 的标签仅仅只是因为它有个第二类斯特林数???然后这么SB的题我还做了半天???
考虑寻找这个题满足题目要求的性质。
本质上来说就是,第一列和最后一列的颜色数量相同,且第二列到倒数第二列中间的颜色必须既在第一列,又在最后一列出现过。
故考虑枚举第一列和最后一列的颜色数量
考虑如何计算答案。
先预处理一个数组
其实是第二类斯特林数,但是我不知道,现推了一遍,转移柿子是很简单且好理解的:
首先对于第一列和最后一列,假设这
然后再看这
最后中间的
故总答案就是
29. CF906C Party
日常做题遇到状压板子题,甚至分这么高。
考虑先把答案是
然后很板的,定义
考虑顺推,即在知道
初始值,对于每个点
时间复杂度
30. CF1793E Velepin and Marketing
先观察一下在最优方案下,每个书如何分配的读者。
显然要将读者按照
考虑一下方案是怎么构成的,发现只有以下两种情况:
- 将开心的读者分成若干个组,且每个组都能保证这些读者是开心的。
- 将所有开心的读者分在一组,外加一些不开心的读者来保证这个组的读者数量从而保证读者开心。
- 对于没有分配在这些组内的读者,一人占一个组。
- 容易发现,如果不是以上两种情况,那么显然可以通过调整得到这种情况。
故考虑定义
假设当前有
,对应分成若干组的情况。 ,对应将前 个分成一个组,补一些不开心的进去,然后剩下的一人一组的情况。
容易发现,随着
瓶颈在于排序。
31. CF808G Anthem of Berland
最开始想了一个
其实是转移冗余了。
看到这个
然后发现这个东西多多少少跟
考虑顺推转移,即知道
- 首先你可以直接失配,即
- 考虑向后匹配一位,即当
或者 是问号的时候,即 的时候,这个时候已经匹配完一个了,那么下面继续的话就需要用到 数组了,考虑一直向前跳 ,假设当前的 满足 ,如果满足 或者 是问号的时候,有 。 的时候,可以全部失配,显然可以 。
最后找到
你可能会认为,你中途失配,即
说实话不太好解释,总之就是这种情况会被剩下的情况考虑到,这样就不用去枚举失配的时候下一位填什么了,直接失配到
时间复杂度
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· 单线程的Redis速度为什么快?
· SQL Server 2025 AI相关能力初探
· AI编程工具终极对决:字节Trae VS Cursor,谁才是开发者新宠?
· 展开说说关于C#中ORM框架的用法!