DP技巧与DP杂题
DP常用技巧
- 增加维数
- 交换答案与状态
- 可行解转最优解
- 删掉本质相同的状态
- 对部分状态
- 遇到转移顺序的困难,考虑记忆化搜索
- 遇到转移细节过多的问题,考虑从
而不是 - 考虑状态时,先把需要记下来的都记一遍,再考虑优化
DP杂题
CF837D (可行性转最优化)
题目
我们把一个数的 roundness 值定义为它末尾
给你一个长度为
数的积的 roundness 值最大。
题解
考虑一个很暴力状态,设
我们发现直接这样转移的复杂度是
所以我们考虑套路可行解转最优解,设
这样子复杂度就降为了
CF677D (分层图dp)
题目
有一个
数据范围:
题解
我们先把数按照种类分组,分成
然后要是直接暴力的状态转移的话,是要TLE的,考虑进行优化(下面这个优化真的太神仙了)。
考虑一个界限
那么当
如果
这样一来,两种加起来的总时间复杂度就是
P1004 [NOIP2000 提高组] 方格取数(去除冗余状态)
题意
给定一个
题解
显然我们可以设
考虑如何优化
首先,两次走的总步数一定是
BZOJ 1801 中国象棋(DP) (去除不必要的维度)
题目
在
说人话就是,不存在三炮共线的情况有多少种
题解
首先,一个显然的想法是进行状压
我们考虑一件事,就是假设前
所以我们可以设
我们考虑转移
- 放0个炮,那么就是:
- 放1个,可以放在还可以放1个炮的列中,也可以放在还可以放2个炮的列中:
- 放2个,可以都放在还可以放1个炮的列中,也可以都放在还可以放2个炮的列中,也可以每边放一个:
[SCOI2008]着色方案 (利用题目性质优化状态)
题目
有
你有
且保证
统计任意两个相邻木块颜色不同的着色方案
题解
一个变态朴素的想法,我们进行
我们意识到一个问题,使相邻木块颜色不同并不需要枚举每一种颜色,事实上,我们只要保证当前颜色不与上一次的颜色相同,那么就是合法的转移,所以我们考虑优化状态
设
我们不能选的状态,就是剩余次数为
[AGC044A] Pay to Win (记忆化搜索,大力出奇迹)
题目
你需要通过如下操作把
- 花
个金币把数字乘 。 - 花
个金币把数字乘 。 - 花
个金币把数字乘 。 - 花
个金币把数字加一或减一。
求最少需要花费的金币。
题解
倒着记忆化搜索,乘法变成除法,遇到除不尽的通过加法调整
这样形成的就是一个深度为
时间复杂度
[USACO2.3]奶牛家谱 Cow Pedigrees (恰好到不超过)
题目
一个有
答案对
题解
考虑到
设
枚举其左儿子大小进行转移即可
复杂度
ZR2022 NOIP十连测Day6 T1 跳棋(有向图+tarjan缩点+拓扑排序/记忆化搜索的一类经典套路)
sb出题人卡常数,下面这个做法过不了
题目
在一个无穷大的跳棋棋盘上,放有
题解
考虑将每个棋子的答案分成两部分
-
周围六格中没有放棋子的部分
拿
记一下各个棋子的位置,然后枚举就行, -
连续跳跃的部分
首先连续跳能够跳到的格子一定不超过
个,因此能跳的位置连上有向边,边数也是 级别的然后用
给有向图缩点,跑拓扑排序或者记忆化搜索得到答案
P7516 [省选联考 2021 A/B 卷] 图函数 (Floyd最短路dp)
PS:因为最短路算法和dp有着千丝万缕的联系,所以我在这里放几道偏图论的题应该问题不大(逃
题解
第一步,拆贡献,我们直接计算每个点对
我们考虑一个问题,两个点可以相互到达,就说明了这两个点不在同一个强连通分量中,那么对于点
那么现在问题转化为,对于前
一个点对会对答案的前缀产生贡献,为了使答案最大化,我们贪心地考虑每个点对都通过一条使得其最小编号点最大的路径,差分一下处理即可
那么怎么求解两点间经过的最小编号点呢?仔细一想,这很符合
时间复杂度 勉强能冲
P3953 [NOIP2017 提高组] 逛公园 (分层图和spfa最短路dp)
题意
给你一张
题解
神仙题!
由于
其中
但是,我们发现这个转移在 (不用考虑转移顺序多是一件美事),时间复杂度
P7077 [CSP-S2020] 函数调用(DAG建模+dp)
题解
首先考虑一个性质,如果只存在
关键点在于:
- 某个函数被调用后序列被乘k,等价于这个函数被执行k次
- 乘法可以使用乘法标记
然后拓扑排序dp处理处理即可
P7962 [NOIP2021] 方差 (差分套路+dp)
题目
给定长度为
其中方差的定义为:数列中每个数与平均值的差的平方的平均值。更形式化地说,方差的定义为
题解
初看这个操作感觉很无厘头是吧?那么试着把它差分吧!
于是我们发现操作等价于交换原数列差分数组中的两个数
然后我们不喜欢那个丑到爆的方差定义,于是设
还有给定的
考虑如何得到最优答案,感性理解一下,答案序列应该是个单谷序列,证明可以考虑调整法,这里不赘述
先将
时间复杂度
P7961 [NOIP2021] 数列 (跟二进制进位有关的dp)
题面
给定整数
对于一个长度为
当这样的序列
计算所有合法序列
题解
由于有进位的情况出现,因此考虑从低位向高位dp
设
时间复杂度
P6758 [BalticOI2013] Vim(线头dp)
原作者题解,这里引用一下LOJ2687 BalticOI2013 Vim 线头DP,因为原作者写的实在是太好了,所以这里建议去原作者博客获得更好的阅读体验,放这里是方便笔者自阅
题解
原题等价于:给出一个序列和两种移动方式,移动过程中必须要经过某一些点,求最小代价。
把连续的f操作和连续的h操作看成线,那么移动路线如下
首先,考虑下面两种移动路线
显然A路线一定没有B路线优
上面的条件等价于对于某一个位置
设
又设
转移:
其中虚线表示新加入的线,红色字表示对应位置的字符类型,黑色字表示位置编号
转移就是把线延长和补全的过程,所以叫做线头DP
代码源省选班 字符串 (子段切分问题)
题面
给定一个长度为 AB?
组成的字符串,求有多少种方式可以把每个 ?
替换为 A
或 B
后,字符串中,长度为 A
或全 B
字串恰好有
题解
一种朴素的状态是: 设
考虑优化,去掉
那么就有转移
其中
二维前缀和优化即可
时间复杂度
ZR2020 提高组十连测 day5 T3 (点边数差异不大时的一种处理图上dp的做法)
题意
过了一阵子的辉夜又开始想起了这件事,她开始在意起如果那时候她真的出去乱走,到底什么时候能回到这里呢?可以把街区抽象为一个连通的无向简单图
题解
树的情况就考虑树形dp,设
时间复杂度
注意到
我们考虑先在原图中找出一棵 DFS 树,其中包含了
- 我们就去掉了原图中所有的环
证明可以考虑反证法,假设删完后存在环,那么至少有一条边环边不在 DFS 树上,环上至少有两个关键点,关键点又被删掉了,出现矛盾
- 新图中任意一个连通块至多与两个关键点相邻
同样考虑反证法,假设存在连通块与大于两个关键点相邻,那么一定存在两个端点处的关键点有 lca,这个 lca 也是关键点并且还没有被删(被删了这几个关键点就分开了),出现矛盾
那么我们就可以对每一个连通块做树形dp,加回关键点的时候在虚树上做高消即可算出每个点的答案,时间复杂度
但是我们注意到,加边带来的至多
ZR2020 提高组十连测 Day10 T2 (树的拓扑序计数于dp中的应用)
题意
你有一个数列
你要对这个数列进行
-
在
数列的末尾加入 或者 。 -
选择一个下标i满足
,然后选择一个数字 满足 或者 ,然后将数字插入到 与 之间。
问有多少种不同的操作序列。这里两个操作序列不同,当且仅当存在某个时刻,使得操作完两个数组的内容不同。
题解
设
而我们知道,有根树的拓扑序数量为
因而直接套树的拓扑序计数的套路,每次注意把新生成的子树大小给除上去就行了,时间复杂度
ZR2023 NOIP赛前20连测 Day5 T2 (根据所求缩小状态个数)
题意
小诗想生成一个长为
取某一值域
她想知道所有能生成的序列权值之和,由于答案过大,你只需告诉她答案对
对于所有测试点,
题解
对于一个序列方案,它的权值即为
然后考虑 dp ,最暴力的做法就是枚举三个值进行转移,时间复杂度是
考虑我们要求的是四个数的
posted on 2023-10-27 17:58 star_road_xyz 阅读(73) 评论(0) 编辑 收藏 举报
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 单线程的Redis速度为什么快?
· 展开说说关于C#中ORM框架的用法!
· Pantheons:用 TypeScript 打造主流大模型对话的一站式集成库
· SQL Server 2025 AI相关能力初探
· 为什么 退出登录 或 修改密码 无法使 token 失效