精华 推荐

概率与期望

黑大帅 2025-9-17 1:24:13 122 浏览 1 点赞 0 收藏

概率与期望

概率论

事件的运算及概率

  • 包含:A⊂BA \subset B,发生 BB 时必然发生 AA,发生 AA 时不一定发生 BB。

  • 并(和)事件:A∪B=A+BA \cup B = A + B,AA 发生或 BB 发生或两者都发生。

  • 交(积)事件:A∩B=ABA \cap B = AB,AA 和 BB 同时发生。

  • 差事件:A−B=AB‾=A−ABA - B = A\overline{B} = A - AB,AA 发生但 BB 不发生,B‾\overline{B} 表示 BB 的对立事件。

  • 互斥事件:AB=∅AB=\varnothing,AA 和 BB 不能同时发生。

  • 对立(逆)事件:A+A‾=S,AA‾=∅A+\overline{A}=S,\quad A\overline{A}=\varnothing,AA 发生时 A‾\overline{A} 不发生,A‾\overline{A} 发生时,AA 不发生。

  • 独立事件:P(AB)=P(A)P(B)P(AB)=P(A)P(B)

    AA 发生与否不影响 BB 的概率,反之亦然。

    • 若 A,BA,B 独立,则 A,B‾A,\overline{B}、A‾,B\overline{A},B、A‾,B‾\overline{A},\overline{B} 也相互独立。
    • 若 A,B,CA,B,C 相互独立,那么
      • A,B,CA,B,C两两独立(但逆命题不成立)
      • P(ABC)=P(A)P(B)P(C)P(ABC)=P(A)P(B)P(C)。
  • 德摩根律:

    $$\overline{A\cup B}=\overline{A}\cap\overline{B}\\ \overline{A\cap B}=\overline{A}\cup\overline{B} $$
  • 加法公式(容斥原理):
    P(A+B)=P(A)+P(B)−P(AB)P(A+B)=P(A)+P(B)-P(AB)
    P(A+B+C)=P(A)+P(B)+P(C)−P(AB)−P(AC)−P(BC)+P(ABC)P(A+B+C)=P(A)+P(B)+P(C)-P(AB)-P(AC)-P(BC)+P(ABC)

  • 减法公式:
    P(A−B)=P(A)−P(AB)P(A-B)=P(A)-P(AB)

  • 对立事件概率:
    P(A‾)=1−P(A)P(\overline{A})=1-P(A)


条件概率与乘法公式

  • 条件概率:在 AA 已发生下 BB 的概率。
    P(B∣A)=P(AB)P(A)P(B\mid A)=\dfrac{P(AB)}{P(A)}

  • 乘法公式:
    P(AB)=P(A)P(B∣A)=P(B)P(A∣B)P(AB)=P(A)P(B\mid A)=P(B)P(A\mid B)


全概率公式与贝叶斯公式(包括在 NOI 大纲内但大概率 useless)

  • 全概率公式({Bi}\{B_i\} 为完备事件组):

    P(A)=∑i=1nP(Bi)P(A∣Bi)P(A)=\sum_{i=1}^{n}P(B_i)P(A\mid B_i)
  • 贝叶斯(逆概)公式:

    P(Bi∣A)=P(Bi)P(A∣Bi)P(A)P(B_i\mid A)=\dfrac{P(B_i)P(A\mid B_i)}{P(A)}

离散型随机变量(一维)

离散型随机变量是指取值为可列(通常是有限或可数无限)集合中某些具体数值的随机变量。

分布列

随机变量 XX 可取值:

X1,X2,…,XkX_1,X_2,\dots,X_k

各取值对应的概率为:

P{X=X1},P{X=X2},…,P{X=Xk}P\{X=X_1\},P\{X=X_2\},\dots,P\{X=X_k\}

分布函数

F(x)=P{X≤x}。F(x)=P\{X\le x\}。

重要性质 离散型一维随机变量的分布函数可视为前缀和):P{a≤X≤b}=F(b)−F(a−1)P\{a\le X\le b\}=F(b)-F(a-1)。

数学期望

E(X)=∑i=1nxipiE(X)=\sum_{i=1}^{n}x_i p_i

若 Y=g(X)Y=g(X),则

E(Y)=∑i=1ng(xi)piE(Y)=\sum_{i=1}^{n}g(x_i)p_i

性质:

  • E(c)=c,E(ax+c)=aE(X)+cE(c)=c,\quad E(ax+c)=aE(X)+c。

  • E(X±Y)=E(X)±E(Y)E(X\pm Y)=E(X)\pm E(Y)

  • 若 X,YX,Y 独立,则 E(XY)=E(X)E(Y)E(XY)=E(X)E(Y)。

方差

D(X)=E(X2)−E2(X)D(X)=E(X^2)-E^2(X)

性质:

  • D(c)=0,D(aX+b)=a2D(X)D(c)=0,\quad D(aX+b)=a^2D(X) 。
  • D(x±y)=D(x)+D(y)±2Cov⁡(X,Y)D(x\pm y)=D(x)+D(y)\pm 2\operatorname{Cov}(X,Y),其中
    Cov⁡(X,Y)=E(XY)−E(X)E(Y)\operatorname{Cov}(X,Y)=E(XY)-E(X)E(Y)为协方差。
  • 若X,YX,Y独立,则 Cov⁡(X,Y)=0\operatorname{Cov}(X,Y)=0,因此 D(X±Y)=D(X)+D(Y)D(X\pm Y)=D(X)+D(Y)。

常见分布

【0–1 分布(伯努利分布)】

进行一次独立试验,成功的概率为 pp,失败的概率为 1−p1-p。(即 n=1n=1 的二项分布)

记作 分布列 数学期望 方差
X∼B(1,p)X\sim B(1,p) P{X=0}=1−p,  P{X=1}=pP\{X=0\}=1-p,\; P\{X=1\}=p E(X)=pE(X)=p D(X)=p(1−p)D(X)=p(1-p)

【二项分布】

进行 nn 次独立试验,每次成功的概率为 pp,失败的概率为 1−p1-p。

记作 分布列 数学期望 方差
X∼B(n,p)X\sim B(n,p) P{X=k}=(nk)pk(1−p)n−kP\{X=k\}=\binom{n}{k}p^k(1-p)^{n-k} E(X)=npE(X)=np D(X)=np(1−p)D(X)=np(1-p)

【几何分布】

进行独立试验,直到第一次成功为止;成功的概率为 pp,失败的概率为 1−p1-p。

记作 分布列 数学期望 方差
X∼G(p)X\sim G(p) P{X=k}=(1−p)k−1pP\{X=k\}=(1-p)^{k-1}p E(X)=1pE(X)=\dfrac{1}{p} D(X)=1−pp2D(X)=\dfrac{1-p}{p^2}

【超几何分布】

从 NN 个物体中抽取 nn 个物体,其中有 KK 个是成功的,N−KN-K 个是失败的。

记作 分布列 数学期望 方差
X∼H(N,K,n)X\sim H(N,K,n) $P\{X=k\}=\dfrac{\binom{K}{k}\binom{N-K}{n-k}}{\binom{N}{n}}$ E(X)=nKNE(X)=\dfrac{nK}{N} D(X)=nK(N−K)(N−n)N2(N−1)D(X)=\dfrac{nK(N-K)(N-n)}{N^2(N-1)}

概率与期望 DP

与组合数 DP 类似,只是在 DP 转移时结合概率或期望的计算。常见有后效性方程,需要移项或高斯消元处理。

【例题 1】Jerry's Protest(纯概率论应用)

#include <bits/stdc++.h>
using namespace std;
using ll = long long;
int main(){
    ios::sync_with_stdio(false);
    cin.tie(nullptr);
    int n; cin>>n;
    vector<int> a(n);
    for(int i=0;i<n;i++) cin>>a[i];
    sort(a.begin(), a.end());
    // 赢 a[i]-a[j] 的概率
    unordered_map<int, double> p;
    for(int i=0;i<n;i++)
        for(int j=0;j<i;j++)
            p[a[i]-a[j]] += 2.0/(n*(n-1));
    // 后手前两把总和的概率
    unordered_map<int, double> q;
    for(auto i : p)
        for(auto j : p)
            q[i.first+j.first] += i.second*j.second;
    double ans = 0;
    for(auto i : p)
        for(auto j : q)
            if(i.first>j.first) ans += i.second*j.second;   
    cout<<fixed<<setprecision(10)<<ans<<'\n';
}

【例题 2】ABC326E(普通期望 DP)

  • 状态:E(x)E(x) 为当前值为 xx 时后续期望工资。

  • 初值:E(n)=0E(n)=0。因为此时无法掷出满足 x<yx<y的 yy。

  • 目标:E(0)E(0)。

  • 转移:$\displaystyle E(x)=\sum_{y=x+1}^{n}\frac{1}{n}\big(A_y+E(y)\big)$。

    E(x)E(x) 需要从 nn 到 00 进行计算,计算过程中对Ay+E(y) A_y+E(y) 动态维护一个后缀和即可 O(n)O(n)解决。

#include <bits/stdc++.h>
#include <atcoder/modint>
using namespace std;
int main(){
    cin.tie(nullptr)->sync_with_stdio(false);
    cin.exceptions(cin.failbit);
    using mint = atcoder::modint998244353;
    int n; cin>>n;
    vector<int> a(n+1);
    for(int i=1;i<=n;i++) cin>>a[i];
    vector<mint> E(n+1);
    mint suf = 0;
    for(int i=n;i>=0;i--){
        E[i] = suf;
        suf += (a[i]+E[i])/n;
    }
    cout<<E[0].val()<<'\n';
}

【例题 3】ABC360E(期望 DP 线性递推)

状态设计

  • E(x)E(x) 代表当进行了 xx 次交换后,黑球位置的期望值。

初始状态

  • E(0)=1E(0)=1

所求结果

  • E(k)E(k)

转移方程

[1,N][1,N] 独立均匀地随机选择两个整数,总方案数 N2N^2。设黑球当前位置为 pp,选择到的两个整数为 i,ji,j。

  • 其中 i≠p且j≠pi\ne p且 j\ne p 的方案数为 (N−1)2(N-1)^2;
    i=p且j=pi =p且 j=p 的方案数为 11。
    这两种情况都不会对黑球的位置产生影响 ,即:

    $$\frac{(N-1)^2+1}{N^2}\,E(x-1)\ \longrightarrow\ E(x). $$
  • 而对于剩余的N2−((N−1)2+1)=2N−2N^2-\big((N-1)^2+1\big)=2N-2种情况 ,黑球位置会被等概率交换到[1,N][1,N] 中除 E(x−1)E(x-1) 以外的其他位置

    因此:

    $$\frac{2N-2}{N^2}\cdot \frac{1}{N}\! \left(\sum_{i=1}^{N - 1} i - E(x-1)\right)\ \longrightarrow\ E(x). $$

将两部分相加并整理,得到

$$E(x) = \frac{(N-1)^2+1}{N^2}\,E(x-1) + \frac{2N-2}{N^2}\cdot \frac{1}{N-1}\! \left(\sum_{i=1}^{N} i - E(x-1)\right). $$

因为 ∑i=1Ni=N(N+1)2\sum_{i=1}^{N} i = \dfrac{N(N+1)}{2},继续化简:

$$\begin{aligned} E(x) &= \frac{(N-1)^2+1}{N^2}\,E(x-1) + \frac{2N - 2}{N^2}.\frac 1 {N - 1}\!\left(\sum_{i = 1} ^ N i - E(x-1)\right) \\ &= \frac{(N-2) \,E(x-1) + N + 1}{N} \end{aligned} $$

最终递推式:

 E(x)=(N−2)E(x−1)+N+1N \boxed{\,E(x)=\dfrac{(N-2)E(x-1)+N+1}{N}\,}
#include <bits/stdc++.h>
#include <atcoder/modint>
using namespace std;
int main(){
    cin.tie(nullptr)->sync_with_stdio(false);
    cin.exceptions(cin.failbit);
    using mint = atcoder::modint998244353;
    int n, k; cin>>n>>k;
    vector<mint> E(k+1);
    E[0] = 1;
    for(int i=1;i<=k;i++) E[i] = ((n-2)*E[i-1]+n+1)/n;
    cout<<E[k].val()<<'\n';
}

【例题 4】ABC382E(概率 DP + 期望 DP + 移项消后效性)

概率部分:先求每个卡包爆出 0,1,2,…,n0,1,2,\dots,n 张稀有卡的概率(简单概率 DP)

  • 状态设计:Pi,jP_{i,j} 表示拆到第 ii 张卡片,累计爆出 jj 张稀有卡的概率。
  • 初始状态:P0,0=1\displaystyle P_{0,0}=1
  • 状态转移:$\displaystyle P_{i,j}=p_i\,P_{i-1,j-1} + (1-p_i)\,P_{i-1,j}$
  • 所求结果:Pn,∗\displaystyle P_{n,*}(第 nn 张拆完后的各个 jj 的概率分布)

然后处理问题所要求的期望部分,枚举每拆一个卡包获取到稀有卡的数量,简单期望 DP 处理:


期望部分:每拆一个卡包获得稀有卡的数量(简单期望 DP)

  • 状态设计:Ei\displaystyle E_i 表示从 ii 张卡片开始拆包,直到至少有 xx 张卡片的期望步数。

  • 初始状态:Ex=0\displaystyle E_x = 0

  • 原始转移式:

    $$E_i=\sum_{j=0}^{n} P_{n,j}\,\big(E_{\min(x,i+j)}+1\big) $$

注意:当 j=0j=0 时出现自依赖项,可移项消环。

  • 移项后的等价式:

    $$\begin{aligned} E_i &= \sum_{j=1}^{n} P_{n,j}\,\big(E_{\min(x,i+j)}+1\big) + P_{n,0}\,(E_i+1) \\ (1-P_{n,0})\,E_i &= \sum_{j=1}^{n} P_{n,j}\,\big(E_{\min(x,i+j)}+1\big) + P_{n,0} \\ E_i &= \frac{\displaystyle \sum_{j=1}^{n} P_{n,j}\,\big(E_{\min(x,i+j)}+1\big) + P_{n,0}} {1-P_{n,0}} \; . \end{aligned} $$
  • 所求结果:E0\displaystyle E_0

#include <bits/stdc++.h>
using namespace std;
int main()
{
    cin.tie(nullptr)->sync_with_stdio(false);
    cin.exceptions(cin.failbit);
    int n,x;
    cin>>n>>x;
    vector<int> a(n);
    for(int i=0;i<n;i++) cin>>a[i];
    vector<double> p(n);
    for(int i=0;i<n;i++) p[i] = a[i]/100.0;
    vector<vector<double>> P(n+1, vector<double>(n+1));
    P[0][0] = 1;
    for(int i=0;i<n;i++)
    {
        for(int j=0;j<=n;j++)
        {
            if(j!=n) P[i+1][j+1] += P[i][j]*p[i];
            P[i+1][j] += P[i][j]*(1-p[i]);
        }
    }
    vector<double> E(x+1);
    for(int i=x-1;i>=0;i--)
    {
        E[i] += P[n][0];
        for(int j=1;j<=n;j++) E[i] += P[n][j]*(E[min(x, i+j)]+1);
        E[i] /= (1-P[n][0]);
    }
    cout<<fixed<<setprecision(10)<<E[0]<<'\n';
}

【例题 5】ABC411E E[max⁡]E[\max](分布函数转化)

目标与记号

  • 设 P{X=x}P\{X=x\} 表示所有骰子掷出后最大值为 xx 的概率,则答案:

    ∑ii×P{X=i}.\sum_{i} i \times P\{X=i\}.

    其中 ii 枚举所有可能出现的点数。

思路

考虑如何求 P{X=x}P\{X=x\} 时,显然所有点数 >x>x 值都不能出现,这很好解决。其次还需要剩下的点数中至少有一个点数为 xx,解决这个限制比较困难。

考虑使用分布函数进行转化。设分布函数为:

F(x)=P{X≤x}.F(x)=P\{X\le x\}.

由分布函数性质:

P{a≤X≤b}=F(b)−F(a−1).P\{a\le X\le b\}=F(b)-F(a-1).

因而

P{X=x}=F(x)−F(x−1).P\{X=x\}=F(x)-F(x-1).

计算 F(x)F(x)

注意到求 F(x)=P{X≤x}F(x)=P\{X≤x\} 与求 P{X=x}P\{X=x\} 的差别,相当于把“剩下的点数中至少有一个点数为 xx”这个限制去除,这样问题就非常容易解决了。

我们维护一下每个骰子的点数 ≤x≤x 的面的数量(记为 cic_i),则有:

F(x)=∏i=1nci6.F(x)=\prod_{i=1}^{n}\frac{c_i}{6}.

将所有骰子的点数进行从大到小的排序,计算完一个点数后就更新一下所有包含这个点数的骰子的 cic_i,并且同步更新上式的值即可。

#include <bits/stdc++.h>
#include <atcoder/modint>
using namespace std;
using ll = long long;
int main()
{
    cin.tie(nullptr)->sync_with_stdio(false);
    cin.exceptions(cin.failbit);
    using mint = atcoder::modint998244353;
    int n;
    cin>>n;
    vector<array<int, 6>> a(n);
    for(int i=0;i<n;i++)
        for(int j=0;j<6;j++)
            cin>>a[i][j];
    map<int, vector<int>> pos;
    for(int i=0;i<n;i++)
        for(int j=0;j<6;j++)
            pos[a[i][j]].push_back(i);
    vector<pair<int, vector<int>>> v(pos.rbegin(), pos.rend());
    mint prod = 1;
    vector<int> cnt(n, 6);
    map<int, mint> f;
    for(auto& [x, w] : v)
    {
        f[x] = prod;
        for(auto i : w)
        {
            prod /= mint(cnt[i])/6;
            cnt[i]--;
            prod *= mint(cnt[i])/6;
        }
    }
    reverse(v.begin(), v.end());
    mint ans = 0;
    for(size_t i=0;i<v.size();i++)
    {
        if(i==0) ans += v[i].first*f[v[i].first];
        else ans += v[i].first*(f[v[i].first]-f[v[i-1].first]);
    }
    cout<<ans.val()<<'\n';
}

【例题 6】ABC412F Socks 4(观察性质消后效性)

设

S=∑i=1NAi.S=\sum_{i=1}^N A_i .

期望题目首先考虑期望 DP。注意到题目中仅有“高桥手中的袜子的颜色”这一个变量,因此可简单设计状态:
E(x)E(x) 表示当高桥手中拥有颜色为 xx 的袜子时,还需要的期望抽取次数。

考虑如何进行状态转移:当高桥手中拥有颜色为 xx 的袜子时,他从抽屉柜中随机取出一只袜子,耗费一次抽取次数。接下来可能的情况有:

  • 取出颜色为 xx的袜子,此时操作终止,后续期望抽取次数为 00。
  • 取出颜色不为 xx的袜子(设颜色为 yy),此操作的概率为 AyS\frac {A_y}S。接下来他会选择能使未来期望抽袜次数最小化的那只袜子放回,后续期望抽取次数为min⁡⁡(E(x),E(y)) \min⁡(E(x),E(y))。

因此可得状态转移方程:

$$E(x)=1+\sum_{y\ne x}\frac{A_y}{S}\min\!\big(E(x),E(y)\big). $$

这是一个自依赖且自依赖包括在 min⁡\min 中的状态转移方程,乍一看似乎无法直接求解,然而我们可以感性理解一下:AiA_i越大,越容易一抽即中,因此 E(i)E(i)越小。故状态转移方程即可化为:

$$E(x)=1+\sum_{\substack{y\ne x\\ A_y\le A_x}}\frac{A_y}{S}E(x) +\sum_{\substack{y\ne x\\ A_y>A_x}}\frac{A_y}{S}E(y). $$

移项可得:

$$\boxed{\,E(x)= \frac{ S+\displaystyle\sum_{\substack{y \neq x\\ A_y>A_x}} A_y E(y) } { S-\displaystyle\sum_{\substack{y \neq x\\ A_y\le A_x}} A_y }\, }. $$

对 AiA_i 排序(设按 AA 递增把颜色重新编号为 1,2,…,N1,2,\dots,N ),则上式化为前后缀可维护的形式:

$$\,E(x)=\dfrac{S+\sum_{yx} A_y}\, $$

实现要点:

  • 先按 AA 升序排序;

  • 维护 ∑y<xAyE(y)\sum_{y<x}A_yE(y) 的前缀与 ∑y>xAy\sum_{y>x}A_y 的后缀,从大到小(或小到大)依次求解 E(x)E(x);

  • 目标为所给颜色 cc 的 E(c)E(c)。

#include <bits/stdc++.h>
#include <atcoder/modint>
using namespace std;
using ll = long long;
int main()
{
    cin.tie(nullptr)->sync_with_stdio(false);
    cin.exceptions(cin.failbit);
    using mint = atcoder::modint998244353;
    int n, c;
    cin>>n>>c;
    vector<int> a(n+1);
    for(int i=1;i<=n;i++) cin>>a[i];
    mint sum = accumulate(a.begin()+1, a.end(), mint(0));
    a[c]++;
    vector<int> o(n+1);
    iota(o.begin()+1, o.end(), 1);
    sort(o.begin()+1, o.end(), [&](int i, int j) { return a[i]<a[j]; });
    vector<mint> E(n+1);
    mint pre=0, suf=0;
    for(int i=1;i<=n;i++) pre += a[o[i]];
    for(int i=n;i>=1;i--)
    {
        pre -= a[o[i]];
        E[i] = (sum+suf)/(sum-pre);
        suf += a[o[i]]*E[i];
        if(o[i]==c)
        {
            cout<<E[i].val()<<'\n';
            break;
        }
    }
}


随机游走模型

线性随机游走(U575231 跃迁)

状态设计
E(i)E(i):从位置 ii 跃迁到 i+1i+1 的一步期望时长。

初始状态
E(1)=1E(1)=1

所求
∑i=1n−1E(i)\displaystyle \sum_{i=1}^{n-1} E(i)

转移方程

E(i)=(1+E(i−1)+E(i))+12E(i)=\frac{(1+E(i-1)+E(i))+1}{2}

(分子前半是先回到 i−1i-1 再到 ii 进而到 i+1i+1;后半是直接到 i+1i+1。)

移项消后效性

12E(i)=1+12E(i−1)  E(i)=2+E(i−1).\frac12 E(i)=1+\frac12 E(i-1)\;\\E(i)=2+E(i-1).

树上随机游走

给定一棵有根树,树的某个结点上有一个硬币,在某一时刻硬币会等概率地移动到邻接结点上,问硬币移动到邻接结点上的期望距离。

需要用到的定义

  • 树 T=(V,E)T=(V,E)

  • 度 d(u)d(u)

  • 边权 w(u,v)w(u,v)

  • 父结点 pup_u、根 root\texttt{root}

  • 子集 sonu\texttt{son}_u、兄弟集 siblingu\texttt{sibling}_u

一、向父结点走的期望距离

设 f(u)f(u) 为从 uu 走到其父 pup_u 的期望距离(f(root)f(\texttt{root}) 不存在),则有。

$$f(u)=\frac{\,w(u,p_u)+\displaystyle\sum_{v\in \texttt{son}_u}\bigl(w(u,v)+f(v)+f(u)\bigr)}{d(u)} $$

分子前半表示直接走向父结点,后半表示先走到子结点、从子结点回到 uu,再到父结点;
分母 d(u)d(u) 表示从 uu 以等概率走向任一邻接点。

化简如下

$$\begin{aligned} f(u) &=\frac{\,w(u,p_u)+\displaystyle\sum_{v\in\texttt{son}_u}\bigl(w(u,v)+f(v)+f(u)\bigr)}{d(u)}\\[4pt] &=\frac{w(u,p_u)+\displaystyle\sum_{v\in\texttt{son}_u}\bigl(w(u,v)+f(v)\bigr)+(d(u)-1)f(u)}{d(u)}\\[4pt] &=\,w(u,p_u)+\sum_{v\in\texttt{son}_u}\bigl(w(u,v)+f(v)\bigr)\\[4pt] &=\sum_{(u,t)\in E} w(u,t)\;+\!\!\sum_{v\in\texttt{son}_u} f(v). \end{aligned} $$
  • 对于叶子结点 ll:f(l)=w(pl,l)\displaystyle f(l)=w(p_l,l)。

  • 当树上所有边的边权都为1时,上式可化为:

$$\boxed{\,f(u)=d(u)+\!\!\sum_{v\in\texttt{son}_u} f(v)\,} $$

即 uu子树的所有结点的度数和,也即 uu子树大小的两倍 −1−1(每个结点连向其父亲的边都有且只有一条,除 uu 与 pup_u 之间的边只有 11 点度数的贡献外,每条边会产生 22 点度数的贡献)。


向子结点走的期望距离

设 g(u)g(u) 为从 pup_u 到其子结点 uu 的期望距离。

$$g(u)=\frac{\,w(p_u,u)+\bigl(w(p_u,p_{p_u})+g(p_u)+g(u)\bigr)+ \displaystyle\sum_{s\in\texttt{sibling}_u}\bigl(w(p_u,s)+f(s)+g(u)\bigr)}{d(p_u)}. $$

分子中的第一部分代表直接走向了子结点 uu,第二部分代表先走向了父结点再由父结点走回来然后再向 uu结点走,第三部分代表先走向 uu 结点的兄弟结点再由其走回来然后再向 uu结点走;分母 d(pu)d(p_u)代表从 pup_u 结点走向其任何邻接点的概率相同。

化简如下

$$\begin{aligned} g(u) &= \frac{ w(p_u,u) + \bigl(w(p_u,p_{p_u})+g(p_u)+g(u)\bigr) + \sum_{s\in \mathrm{sibling}_u} \bigl(w(p_u,s)+f(s)+g(u)\bigr)}{d(p_u)} \\[2pt] &= \frac{ w(p_u,u) + w(p_u,p_{p_u}) + g(p_u) + \sum_{s\in \mathrm{sibling}_u} \bigl(w(p_u,s)+f(s)\bigr) + (d(p_u)-1)g(u)}{d(p_u)} \\[2pt] &= w(p_u,u) + w(p_u,p_{p_u}) + g(p_u) + \sum_{s\in \mathrm{sibling}_u} \bigl(w(p_u,s)+f(s)\bigr) \\[2pt] &= \sum_{(p_u,t)\in E} w(p_u,t) + g(p_u) + \sum_{s\in \mathrm{sibling}_u} f(s) \\[2pt] &= \sum_{(p_u,t)\in E} w(p_u,t) + g(p_u) + \bigl(f(p_u) - \sum_{(p_u,t)\in E} w(p_u,t) - f(u)\bigr) \\[2pt] &= g(p_u) + f(p_u) - f(u). \end{aligned} $$

初始状态为 g(root)=0g(root)=0。

参考实现(无权树)

vector<int> G[MAXN];

void dfs1(int u, int p) {
  f[u] = G[u].size();
  for (auto v : G[u]) {
    if (v == p) continue;
    dfs1(v, u);
    f[u] += f[v];
  }
}

void dfs2(int u, int p) {
  if (u != root) g[u] = g[p] + f[p] - f[u];
  for (auto v : G[u]) {
    if (v == p) continue;
    dfs2(v, u);
  }
}


【题目清单】

概率论

  • P8804 [蓝桥杯 2022 国 B] 故障(贝叶斯公式)
  • P6154 游走(DAG DP)
  • CF626D Jerry's Protest
  • ABC380G
  • P2221 [HAOI2012] 高速公路(线段树维护期望)

概率 DP

  • CF148D Bag of mice
  • CF167B Wizards and Huge Prize(背包+概率 DP)
  • ABC382E Expansion Packs(概率 DP + 期望 DP + 移项消后效性)
  • P4284 [SHOI2014] 概率充电器(树上概率 DP)
  • P12292 [蓝桥杯 2024 国 Java A] 斗蛐蛐(有后效性)
  • P12293 [蓝桥杯 2024 国 Java A] 合并小球

期望 DP

  • CF1925D Good Trip
  • ABC326E Revenge of "The Salary of AtCoder Inc."
  • ABC360E Random Swaps of Balls
  • ABC402E Payment Required(推荐,背包+状压+期望 DP)
  • ABC411E E [max](分布函数)
  • ABC412F Socks 4(观察性质消后效性)
  • P1850 [NOIP 2016 提高组] 换教室
  • P2473 [SCOI2008] 奖励关(状压+期望 DP)
  • P4206 [NOI2005] 聪聪与可可
  • P2081 [NOI2012] 迷失游乐园(树上期望 DP)
  • P3239 [HNOI2015] 亚瑟王

随机游走

  • U575231 跃迁(线性随机游走)
  • CF1823F Random Walk(树上随机游走)
  • CF2040E Control of Randomness(树上随机游走)
  • P3211 [HNOI2011] XOR和路径(高斯消元)
  • P3232 [HNOI2013] 游走(高斯消元)
  • P6899 [ICPC 2014 WF] Pachinko(高斯消元)

一些 XCPC 的题目

XCPC 经常出概率与期望 DP(由于 Codeforces 的限制,Gym 的题目需要复制链接粘贴到地址栏打开):

评论

0 条
还没有评论。