[模拟赛] 瘟疫(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;
}
posted @ 2025-09-05 19:58  _huangweiliang  阅读(16)  评论(0)    收藏  举报