概率与期望
1. 算法分析
数学期望的性质
- 设X是随机变量,C是常数,则E(CX)=CE(X)。
- 设X,Y是任意两个随机变量,则有E(X+Y)=E(X)+E(Y)。
- 设X,Y是相互独立的随机变量,则有E(XY)=E(X)E(Y)。
- 设C为常数,则E(C)=C。
特点分析
数学期望的题目一般都是DAG,起点唯一,终点很多的情况,这种情况下一般都是dp处理,从终点往起点做dp,答案就是f[1].
解法可以直接递推:反向建图,然后topsort跑出拓扑序,按照拓扑序做dp;
也可以记忆化搜索,直接正向做记忆化搜索。
规律总结
这里要注意的一点:
随机变量X = Y1+Y2+Y3+…+Yn(认为Yi里面有ti个元素)
按照公式E(X) = E(Y1)+E(Y2)+…+E(Yn)
可是一般计算的时候都是dp[x] = dp[y1]*p1+dp[y2]*p2+…为什么呢?
因为递推的过程中,算出dp[y1]时是认为只有t1个元素,而在算dp[x]时,元素个数是t1+t2+t3+…+tn个,所以要把原来算出来的期望dp[y1] * p1表示原先算出来的期望E’需要先转化为当前期望E,二者的转换关系为E’ * p1=E
因此,我们可以得出结论:
从起点开始递推,当前的期望=累加【子状态的期望 * 子状态出现的概率】
2. 例题
2.1 期望的线性
bzoj2969矩形粉刷
题意:
小M粉刷一个大木板。大木板实际上是一个W*H的方阵。小M得到了一个神奇的工具,这个工具只需要指定方阵中两个格子,就可以把这两格子为对角的,平行于木板边界的一个子矩形全部刷好。小M乐坏了,于是开始胡乱地使用这个工具。假设小M每次选的两个格子都是完全随机的(方阵中每个格子被选中的概率是相等的),而且小M使用了K次工具,求木板上被小M粉刷过的格子个数的期望值是多少。
题解: 由于期望具有可加性,因此可以计算出每个格子被染色的概率,加起来即为答案。
那么一个格子被染色的概率即为1-(每次都不被染色的概率)^k。
考虑单次染色没有没染的情况:选定的两个点都在左边、上边、右边、下边,但是会发现四个角的部分会计算两次,因此还需要减掉两个点都在左上、左下、右上、右下的情况。然后求幂加起来即可。
代码:
#include <cmath>
#include <cstdio>
inline double squ(double x) {
return x * x;
}
int main() {
int k , n , m , i , j;
double ans = 0;
scanf("%d%d%d" , &k , &n , &m);
for(i = 1 ; i <= n ; i ++ )
for(j = 1 ; j <= m ; j ++ )
ans += 1 - pow((squ((i - 1) * m) + squ((j - 1) * n) + squ((n - i) * m) + squ((m - j) * n)
- squ((i - 1) * (j - 1)) - squ((i - 1) * (m - j)) - squ((n - i) * (j - 1)) - squ((n - i) * (m - j))) / squ(n * m) , k);
printf("%.0lf\n" , ans);
return 0;
}
2.2 DAG期望
acwing217绿豆蛙的归宿
题意:
一个有向无环的连通图,起点为1,终点为N,每条边都有一个长度。数据保证从起点出发能够到达图中所有的点,图中所有的点也都能够到达终点。绿豆蛙从起点出发,走向终点。到达每一个顶点时,如果有K条离开该点的道路,绿豆蛙可以选择任意一条道路离开该点,并且走向每条路的概率为 1/K 。现在绿豆蛙想知道,从起点走到终点所经过的路径总长度的期望是多少?
N~1e5, M~2N
代码:
#include <bits/stdc++.h>
using namespace std;
int const N = 1e5 + 10;
int n, m, dout[N], e[N * 2], ne[N * 2], idx, h[N], w