一道期望dp的题,推了好久的式子一直算不清楚,最后发现是我对排列数的理解有偏差😥
题面
题目大意: 初始情况为只有n个点的无向图,每一次随机两个点(可能相同),如果这两个点连上边之后满足下列条件就连边,不然图不变。条件: - 无重边自环 - 每个点的度数小于等于2
不能继续操作就终止,求终止的期望步数
思路
- 可以看出是有重叠的子问题的,在某种情况下开始的期望步数是定的,可以想到用dp
- 每个点的度数小于等于2,那么2度点不能继续连边,0度点不和2度点连边,1度点有一点特殊。考虑1度点的连边情况,有可能1度点和1度点连,这个时候形成长度为2的链,另一种情况是1度点2度点连边,可以发现这两种情况需要分别分析。所以状态比较明显了: dp[i][j][k] 表示当前有 i 个0度点, j 个1度点,这 j 个1度点中有 k 条长为2的链,所需要达到终止条件的期望步数
- 状态转移:
- 0度和0度: i * (i−1)
- 0度和1度(不在长为2的链上): i * (j−2*k) * 2 //一开始没乘后面的2怎么算也算不对🤡
- 0度和1度(在长为2的链上): i * 2 * k * 2
- 1度(不在长为2的链上)和1度(不在长为2的链上): (j−2*k) * (j−2*k−1)
- 1度(不在长为2的链上)和1度(在长为2的链上): (j−2*k) * 2 * k * 2
- 1度(在长为2的链上)和1度(在长为2的链上): 2 * k * (2*k−2)
这是所有合法转移,用记忆化搜索的方式写很方便
最终状态 dp[0][0][0] = 0
AC代码:
1 |
|
另一种状态的设计方法
设 dp[i][j][k] 为现在有 i 个0度点, j 条长为2的链, k 条长大于2的链,要达到最终状态所需要的期望步数
状态转移
- 0度和0度: i * (i−1)
- 0度和短链: i * 2 * j * 2
- 0度和长链: i * 2 * k * 2
- 短链和短链: 2 * j * (2*j−2)
- 短链和长链: 2 * j * 2 * k * 2
- 长链和长链(成环): 2 * k
- 长链和长链(成链): 2 * k * (2*k−2)
AC代码
1 |
|