做题小计 ARC170E
我觉得很强的题目。
传送门:Luogu
分析
分析问题本质。
根据大量推理,发现问题再描述这样一个东西:
一开始有 \(a,b\) ,一开始有 \(p\) 的概率使得 \(a\) 加一, \(1-p\) 的概率使得 \(b\) 加一。
进行 \(n-1\) 次操作,每次操作如下:
- 有 \(p\) 的几率与上一次操作的数相同
- 有 \(1-p\) 的几率与上一次操作的数不同
使选定的数加一。
最后问 \(\frac{(a+1)\times a+(b+1)\times b}{2}\) 的期望值为多少。
Solution 1
无脑 dfs。
每次枚举下一次取 \(a\) 还是 \(b\) ,最后统计答案即可。
时间复杂度 \(O(2^n)\)
Solution 2
每次在最后计算答案,这样很吃亏。
考虑每一位的贡献,计算到当前位时得到贡献,把所有贡献乘上几率加起来即可。
也是 dfs 。
Solution 3
发现计算了很多重复的状态。
定义 \(f_{i,j,0/1}\) 表示目前进行了第 \(i\) 次操作,其中操作时使得 \(a=j\) 。\(0\) 表示这一次取了前面的,\(1\) 表示取了后面的。状态存的是转移到这个式子的几率。
转移方程式明显,枚举上一次转移即可。
\(f_{i,j,0}=f_{i-1,j-1,0}\times p + f_{i-1,j-1,1}\times (1-p)\)
\(f_{i,j,1}=f_{i-1,j,0}\times (1-p) + f_{i-1,j,1}\times p\)
此次的贡献即为 \(f_{i,j,0}\times j + f_{i,j,1}\times (i-j)\) 。
暴力枚举即可。时间复杂度 \(O(n^2)\)
Solution 4
dp 式子很不好优化。
有 \(2\) 个 \(\times j\) 的项卡住了我们的优化。
这个时候可能要重新思考一下。
我们考虑把原问题转化一下。
与其有两个数 \(a,b\) ,不妨把所有情况归为同一个方向。
每次操作相当于做一次有用操作:给当前的数加一或者无用操作,给另一个数加一。
此时不需要考虑另一个数,因为我们把贡献钦定为只有当前正方向才会产生贡献。
初始值不再设为 \(f_{0,0,0}=1\) ,而是 \(f_{0,0,0}=f_{0,0,1}=1\)
这样贡献只需要计算 \(f_{i,j,0}\times j\) 即可。
Solution 5
考虑 \(\sum\limits_{j=1}^n f_{i,j,0}\times j\) 本质上计算的是什么。
不就是计算取到第 \(i\) 位时所有大小的期望值吗?
我们考虑直接计算大小的期望值。
定义 \(f_{i,0}\) 表示第 \(i\) 次操作取当前数长度期望, \(f_{i,1}\) 表示第 \(i\) 次取另外一个数的期望。
那么很明显,取前面会使我们的期望长度 \(+1\) ,因为我们只考虑前面的数。取后面是没有贡献的。
答案和上面方法统计一样,记录每一位期望值的和即可。
这时转移就很简单了:
\(f_{i,0}=p\times f_{i-1,0}+(1-p)\times f_{i-1,1}+1\)
\(f_{i,1}=p\times f_{i-1,1}+(1-p)\times f_{i-1,0}\)
\(ans=ans+f_{i,0}\)
时间复杂度 \(O(n)\)
Solution 6
对上面的式子使用矩阵快速幂即可。
时间复杂度 \(O(k^3\log n)\)