12.8省选总结

本文总结了树形DP、数位DP、状态压缩DP、概率DP等动态规划算法的经典应用场景及解题思路,包括典型例题解析及代码实现。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

常见dp总结:

目录

树形DP

完成情况题目出处
ACChoosing Capital for TreelandCodeforces 219 D #135
A simple graph problemHDU 4980

数位DP

完成情况题目出处
Round NumbersPOJ 3252
F(x)HDU 4734
ACBeautiful numbersCodeforces 55 D #51
阿里云秘钥池计蒜之道2017复赛

状压DP

完成情况题目出处
ACLittle Pony and Harmony ChestCodeforces 453 B #259
A Graph ProblemCDOJ 1296

概率DP

完成情况题目出处
ACAeroplane chessHDU 4405
ACBag of miceCodeforces 148 D #105
HighlanderSGU 385

树形dp:

树形dp的套路做法大概是两种,其一是链上统计,其一是换根操作。链上统计,顾名思义,就是只统计root到它的这条链的信息,然后用lca这样的方式算答案。换根操作就是如果要统计每个点的答案,那么我们就要想办法在很短的时间内将之前的dp数组转移到现在的。

例题:

给你一颗树,所有节点为黑色,现在你需要将某些节点改变为白色,使得每条边的两端至少有一个白色节点,问最少需要改变多少节点。
f[i]表示这个点不改的时候,填完子树用的代价。g[i]表示这个点要改的答案。
那么转移比较明显:f[i]=g[son]g[i]=1+minf[son]g[son]
依赖背包
首先,我们易得一个nv2的做法。下面考虑优化。我们注意到多出来的v实际上是合并背包,两个背包合并。而01背包是一个物品合并到背包上,所以少一个v。那么改一下dp的定义,left[i]表示i这个物品及其之后的dfs序上的子树最值,然后转移就比较显然了。
codeforces 219 D
首先我们可以以每一个为root做一次,但是明显要TLE。所以我们要换根。如何换,我们注意到当一棵树转移到其子树的时候,实际上就只有他与儿子的那条边的贡献要变,只用改这个点就可以了。
poj 3170
就是找重心。只不过用dp找,dp[i]表示这颗子树的大小,然后乱搞
给你一颗树,每个节点都有权值,有些节点也是陷阱。现在从树上一点出发,不经过重复的节点,到另一个节点终止,并且经过最大不超过C个陷阱(C<4),要求路径的权值和最大。
dp[i][j]表示i这个点向下走i个陷阱的最值,转移明显。但是我们注意到这几个点不能直接重做,所以考虑换根,就是换根之后只用考虑是不是从其儿子转移上来的就可以了。
HDU 4980
注意到一条边最多会有2个人走,所以设dp[i][j]表示i这个点上有j个人向上走。转移的时候,我们考虑子树之间的匹配,就是考虑这几个子树之间有多少个相互转弯,然后还要加上拐点的权值。

数位dp:

需要满足的要求
1.求某个区间[lr]满足某个条件的数的个数。
2.这种统计有前缀性。
此时我们就可以用前缀和相减得到答案了。

例题

求区间[A,B]间恰有K个8的数的个数。
裸题,设dp[l][k]表示长度为l,有前导零,有k个八的个数,转移的时候,我们直接枚举中间的断点来转移。(也可以直接公式转移)统计答案的时候,根据顶不顶上界乱搞就好了。
poj 3252
dp[i][j]表示长度为i01j个的数有多少个,转移显然。(当然要注意j可能是负数,要把下标转移一下)。
HDU 4734
dp[i][res]表示当前有i位,还可以有res的数的个数。
Codeforces 55D
首先,我们注意到,我们可以状压,然后转移。但是这样复杂度太高了,所以考虑优化。我们有这个lcm最大是2520,所以我们可以传的时候传mod2520的值,然后又注意到,这个mod2520是可以离散化的,就是算出来只有48个,就可过了。
计蒜之道2017复赛(阿里云秘钥池)
我们设dp[i][j]表示第i位,这一位为j,然后根据此,我们可以得到一个转移:
dp[i][j]=dp[i1][gcd(i,j)==1],这样子,是p2logn,要炸,那么考虑转移用莫比乌斯反演优化。
我们有
dp[i][j]=p1j=1d|i,d|jμ(d)×dp[i1][j]=d|iμ(d)pdj=1dp[i1][j×d]
这样dp[i1][jd]可以在nlog的时间搞出来。

状压dp:

首先这类问题的基本特征是数据很小(一般只有15),而且感觉如果不压的话,要讨论很多种情况。
旅行商问题
dp[i][s]表示现在在i,已经走过了s的最小值,转移显然。
CodeForces 453B
注意到b[i]不可能大于60(如果大于,我们为什么不用1呢),所以我们压一下60以内的素数。dp[i][s]表示前i个达到s的最小值,转移的时候通过枚举下一个素数是多少来转移,就是dp[i][s]=dp[i1][sq]+abs(qa[i]),其中q是枚举的素数。
CDOJ 1296
一堆dp方程
dp1[s]表示不通过其他的点,集合中的点互相联通的最少边,实际是一个连通性问题,答案要么是不行,要么是n1
dp2[s]表示可以通过其他的点的最少边。那么如何从dp1转移呢。我们注意到,如果有dp2[s],那么它可以从dp2[s+1...]转移,这里的意思是通过枚举通过哪些点变成了联通。可以证明是3n的。
dp3[s]表示一个联通块的连通性,这里压的是块,转移就是dp2直接转移,意义是这几个块全部联通。
dp4[s]表示可以不连通的代价,那么把这个s拆开,然后从dp3一个一个加上去。

概率与期望dp

通过高消,系数转移,拓扑序等做。

例题:

给出一张有向图G = (V, E)。(DAG)顶点i的权值为Wi 。给出Pu, v表示顶点u经过边(u, v)到顶点v的概率。若某点i发出边概率和为Pi ,那么在顶点i时有1-Pi的概率停止行动。定义路径权为这条路径上所有点权之和。问从一个顶点s开始,在每次按照指定的概率走的前提下,到某一顶点停止行动时所走的路径权的期望值。
dp[i]表示走到i的期望。然后转移的时候,枚举他的前驱,然后他的前驱可以Pa/timesdp[a] 转移过来,不要忘了还要加上这个点的权值。
(非DAG)
我们可以得到n个方程组,然后设0点为x,高斯消元。
HDU 4405
我们设dp[i]表示i点还要期望投多少次骰子,由全概率公式得dp[i]=dp[i+1..6]+16,还有飞跃点的以及连续飞跃点的。
Codeforces 148D
dp[i][j]表示王妃开始抓时有i只白的,j只黑的,然后讨论情况得到转移。
SGU 385
f[i,j,k]表示了错位排列中i个数字已经确定,最长环为 j,且有 k 个 长度为 j 的环的方案数。
转移等如下:

一个m×n的棋盘,左上至右下编号为(1, 1)至 (m, n),并给定每个格子到周围四个格子的概率。一个骑士从(1, 1)开始,按照给定概率走,问到达(m, n)的期望步数。题目保证从任一格开始到(m, n)的概率均为1 。
明显高消,但是会TLE。我们注意到实际上只有两侧有系数,所以可以优化一个nm

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值