概率与期望

创建时间:2025-12-03


概率

概率的概念

对以一个事件 \(A\),用一个 \(0\)\(1\) 之间的实数 \(P(A)\) (Probability)表示其可能性大小。\(P(A)\) 越大,则事件 \(A\) 发生的可能性越大;反之,可能性越小。特别的,当 \(P(A)=1\) 时,\(A\) 一定发生,将 \(A\) 称为一个必然事件;当 \(P(A)=0\) 时,\(A\) 不可能发生,将 \(A\) 称为一个不可能事件。

定义事件 \(A\)\(B\) 同时发生的概率为 \(P(AB)\)\(A\)\(B\) 至少一个发生的概率为 \(P(A+B)\),由容斥原理知 \(P(A+B)=P(A)+P(B)-P(AB)\)

称事件 \(A\)\(B\) 为独立事件当且仅当 \(A\)\(B\) 都不影响对方事件的结果;\(A\)\(B\) 为互斥事件当且仅当 \(A\)\(B\) 不可能同时发生,即 \(P(AB)=0\)

容易发现,对于独立事件 \(A,B\),有

\[P(AB)=P(A)P(B) \]

对于互斥事件 \(A,B\),有

\[P(A+B)=P(A)+P(B) \]

概率的应用

概率有关的题目通常顺推解决,因为其起点状态很容易得到。

POJ-3071 Football 为例。给定 \(2^n\)\(n\le7\)) 支球队。每轮将剩余球队编号升序排列,令第一支球队对阵第二支队,第三支球队对阵第四支球队,以此类推,并淘汰败者。给定 \(p_{i,j}\) 表示编号为 \(i\) 的球队击败编号为 \(j\) 的球队的概率,求最有可能获得冠军的球队。

很容易发现比赛过程呈一颗满二叉树,每次在两个节点间决出胜者作为父节点。故若第 \(i\) 轮后 \(j\) 未淘汰,则 \(j\) 可能对阵的球队编号构成一个长度为 \(2^i\) 的区间。

由于 \(n\) 很小,所以可以设 \(dp_{i,j}\) 表示 \(i\) 轮后编号为 \(j\) 的球队未淘汰的概率,直接暴力枚举 \(j\) 对阵的球队转移即可,复杂度 \(O(4^n)\)

代码:

#include <iostream>
#include <algorithm>

using namespace std;

const int MAX_N = 150;

int n;
double p[MAX_N][MAX_N], dp[10][MAX_N];

int main() {
	cin.tie(0)->sync_with_stdio(false);
	
	while (true) {
		cin >> n;
		if (n == -1)
			break;
		
		for (int i = 1; i <= 1 << n; i++)
			for (int j = 1; j <= 1 << n; j++)
				cin >> p[i][j];
		
		fill(dp[0] + 1, dp[0] + (1 << n) + 1, 1);
		for (int i = 0; i < n; i++)
			for (int j = 1; j <= 1 << n; j++) {
				int t = (j - 1 >> i) ^ 1;
				dp[i + 1][j] = 0;
				for (int k = (t << i) + 1; k <= t + 1 << i; k++)
					dp[i + 1][j] += dp[i][j] * dp[i][k] * p[j][k];
			}
		
		cout << max_element(dp[n] + 1, dp[n] + (1 << n) + 1) - dp[n] << '\n';
	}
	return 0;
}

期望

期望的概念

设事件 \(A\) 的结果 \(X=\{x_1,x_2,\cdots,x_n\}\),令 \(P(x)\) 表示结果为 \(x\) 的概率,则定义 \(X\) 的期望(Expectation) \(E(X)=\sum x_iP(x_i)\),也可以认为是 \(X\) 的带权平均值。

根据定义易得:

\[E(aX)=aE(x) \]

\[E(X+Y)=E(X)+E(Y) \]

\[E(aX+bY)=aE(X)+bE(Y) \]

这也被称作期望的线性性。

注意:期望线性性不要求事件 \(X, Y\) 独立。

期望的应用

期望有关的问题通常倒退求解,因为其终点状态很容易得到。

SPOJ - FAVDICE Favorite Dice 为例:有一个有 \(n\) 个面的骰子,要使 \(n\) 个面都至少出现一次,求需要投掷骰子次数的期望。

先考虑问题的简化版:求需要抛硬币抛出正面的期望次数。

\(E(X)\) 为其期望次数。显然至少要抛一次。若第一次结果为正面,则不需要再抛;否则,还要再抛 \(E(X)\) 次。故 \(E(X)=1+\frac 1 2 E(X)\),而这是一个一元一次方程!移项解得 \(E(X)=2\)

回到原问题,设 \(dp_i\) 表示出现 \(i\) 个面的期望次数。显然,\(dp_n=0\)。如果第一次结果为已出现的面,则还要抛 \(dp_i\) 次;否则抛 \(dp_{i+1}\) 次。故 \(dp_i=1+\frac i n dp_i+\frac {n-i} n dp_{i+1}\),解得 \(dp_i=dp_{i+1}+\frac n {n-i}\)

代码:

#include <iostream>
#include <iomanip>

using namespace std;

const int MAX_N = 1050; 

int t, n;
double dp[MAX_N];

int main() {
	cin >> t;
	while (t--) {
		cin >> n;
		dp[n] = 0;
		for (int i = n - 1; i >= 0; i--)
			dp[i] = dp[i + 1] + 1.0 * n / (n - i);
		cout << fixed << setprecision(2) << dp[0] << '\n';
	}
	return 0;
}

期望 DP 的其他题目:

P4550 收集邮票
P1291 [SHOI2002] 百事世界杯之旅
POJ - 2096 Collecting Bugs
HDU - 4405 Aeroplane chess

posted @ 2026-06-02 16:44  xubaichuan  阅读(8)  评论(0)    收藏  举报