[模拟赛] 瘟疫(ill)
题目描述:
有 \(n\) 个连通块,第 \(i\) 个连通块有 \(a_{i}\) 个点。接下来进行 \(n\) 次操作,每次选择一个点将其所在的联通用块染黑,问第一个连通块被染黑的期望天数。
解题思路:
初步思路,枚举第一个连通块被染黑的天数,计算概率然后相加。但是发现概率极其难求。
所以更换思路,假定我们已知染色顺序,同时钦定假定第 \(i\) 个连通块的染色时间为 \(t_{i}\),那么第一个连通块的时间可以表示为
\[1+\sum _{i=2}^{n} [t_{i} < t_{1}]
\]
那么如果不知道染色顺序然后求期望呢?式子可以变形为:
\[E(1+\sum _{i=2}^{n} [t_{i} < t_{1}])
\]
根据期望的线性性可推出:
\[1+\sum _{i=2}^{n} E([t_{i} < t_{1}])
\]
那么对于 \(i\) 求 \(E([t_{i} < t_{1}])\) 即可,假如 \(t_{i} < t_{1}\) 的概率为 \(p_{i}\),那么\([t_{i} < t_{1}]\) 的期望就是 \(1 \times p_{i}+0 \times (1-p_{i}) = p[i]\)。
那么求 \(p_{i}\) 即可,对于 \(p_{i}\),来说有用的只有 \(1\) 和 \(i\) 的相对位置关系,其余点排在哪里都不会有问题,所以其余点的总方案数为 \((n-2)!\),放在所有地方的概率都相等,所以只要考虑 \(i\) 在 \(1\) 之前的概率,概率显然为 $ \frac{a[i]}{a[i]+a[1]}$。
代码实现:
#include<bits/stdc++.h>
using namespace std;
const int N = 1e5 + 10;
int n;
double ans, a[N];
int main(){
freopen("ill.in", "r", stdin);
freopen("ill.out", "w", stdout);
cin >> n;
for(int i = 1; i <= n; i++) cin >> a[i];
for(int i = 2; i <= n; i++) ans = ans + a[i] / (a[i] + a[1]);
printf("%.3lf\n", ans + 1);
return 0;
}

浙公网安备 33010602011771号