[算法学习笔记](超全)概率与期望

文章讲述了在OI大陆上的papermouse参与抽奖及表白1832的概率计算,引入了概率、期望和条件概率等概念,并通过实例演示如何运用这些理论解决实际问题,如彩票奖金计算和游戏策略设计。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

引子

先来讲个故事······

话说在神奇的OI大陆上,有一只paper mouse

有一天,它去商场购物,正好是11.11,商店有活动

它很荣幸被选上给1832抽奖

在抽奖箱里,有3个蓝球,12个红球

paper mouse能抽3次

蒟蒻的paper mouse就疑惑了:抽到至少1个蓝球的概率是多少???

Answer:

总共有15个球

只抽到1个蓝球的概率是\frac{C_{3}^{1}*C_{12}^{2}}{C_{15}^{3}}\approx0.435165(很好理解吧,在4个蓝球里取一个,再在11个红球里面取3个,总共是在15个里面取4个)

抽到2个蓝球的概率是\frac{C_{3}^{2}*C_{12}^{1}}{C_{15}^{3}}\approx0.079121

抽到3个蓝球的概率是\frac{C_{3}^{3}*C_{12}^{0}}{C_{15}^{3}}\approx0.002198

所以总概率就是三者之和,即0.435165+0.079121+0.002198=0.516484\approx\frac{129}{250}

我们也可以反过来分析:如果paper mouse运气爆棚,一个蓝球都没有抽到

那么其对立事件就一定会有至少一个蓝球

所以概率就是:1-\frac{C_{12}^{3}}{C_{15}^{3}}\approx1-0.483516=0.516484\approx\frac{129}{250}

也就是说,paper mouse有接近\frac{1}{2}的概率给心爱的1832送上礼物······

概率

概率就是随机事件出现的可能性大小

For example,上面的故事里就涉及到概率

若某种事件重复了N次,其中A事件出现了M次,出现A事件的概率就是\frac{M}{N}

同时,0\leq \frac{M}{N}\leq 1,用P()表示

即:P(A)=\frac{M}{N}

1.1 条件概率与全概率

条件概率公式:

如果事件A发生的概率为P(A),事件B单独发生的概率为P(b)

若B必须在A发生之后发生,则B发生的概率就是条件概率,P(B)=P(A|b)=\frac{P(AB)}{P(b)}

(是不是还比较好理解?真正shit的才刚刚开始)

全概率公式:

如果事件 B1, B2,⋯, Bn 构成一个完整的样本空间,且两两互斥,P(Bi) > 0。 则对于任意事件 A 有:P(A)=\sum_{i=1}^{n}P(A|B_i)P(B_i),这就是全概率公式

思想就是:P(A)不是很好求,但是把P(A)拆开计算P(A|Bi)P(Bi)就相对好算一些

举个例子:

paper mouse去表白1832了
他每次写情书,1832都有0.5的概率看见
而第一次看见,1832有0.2的概率同意他
第二次看见时,1832有0.5的概率同意他
第三次看见时,1832一定会同意他的请求 

求paper mouse获得1832爱情的概率

通过全概率公式:

事件A是paper mouse陷入爱河

事件集合B是:B={B_0,B_1,B_2,B_3},B_i表示paper mouse表白了i次

P(A)=P(AB_0)+P(AB_1)+P(AB_2)+P(AB_3)

            = P(A|B_0)P(B_0) + P(A|B_1)P(B_1) + P(A|B_2)P(B_2)+ P(A|B_3)P(B_3)

            =0+C_{3}^{1}*0.5^{3}*0.2+C_{3}^{2}*0.5^{3}*0.5+C_{3}^{3}*0.5^{3}*1

            =0.3875

所以paper mouse表白成功的概率高达0.3!(喜)

期望

炸裂的东西来了

先看看期望的定义

1.1 期望定义

如果随机变量只取得有限个值或无穷能按一定次序一一列出,其值域为一个或若干个有限或无限区间,这样的随 机变量称为离散型随机变量。

离散型随机变量的一切可能的取值 Xi 与对应的概率 P(Xi) 乘积之和称为该离散型随机变量的数学期望,记为 E(X) ,简称期望。

怎么样?是不是蛮有意思的?

换一种通俗但不精确的方式阐述一下(涉及下定义内容,非xxs请谨慎观看):

期望就是    某件事发生的概率集合中的每一个数    对其对应值的乘积    的和

一个普通骰子,众所周知有六面,对应1~6

每一面转到的概率就是 \frac{1}{6},所以:

E(X)=\frac{1}{6}*1+\frac{1}{6}*2+\frac{1}{6}*3+\frac{1}{6}*4+\frac{1}{6}*5+\frac{1}{6}*6

            =\frac{1}{6}*(1+2+3+4+5+6)

            =3.5

所以也可以这么说:

数学期望可以理解为某件事情大量发生之后的平均结果。

来个难点的:

设一张彩票为 2 元,每售 100000 张开奖,假每张彩票有一个对应的六位数号码,奖次如下:

  • 安慰奖:奖励 4 元,中奖概率0.1
  • 幸运奖:奖励 20 元,中奖概率 0.01
  • 手气奖:奖励 200 元,中奖概率 0.001
  • 一等奖:奖励 2000 元,中奖概率 0.0001
  • 特等奖:奖励 20000 元,中奖概率 0.00001

那公司到底是亏还是赚呢?

我们来简单计算一下,对于每一位购买彩票的用户,公司可能支出为: 

0.14+0.01*20+0.001*200+0.0001*2000+0.00001*20000=1.2

所以公司期望赚0.8元

1.2 期望的线性性质

设 X, Y 是任意两个随机变量,则有

  • E(X + Y ) = E(X) + E(Y )
  • E(aX + bY ) = aE(X) + bE(Y ) 

证明略

再举个栗子:

同时仍一颗骰子的期望为3.5

同时扔两颗骰子的概率是3.5+3.5=7

1.3 条件期望与全期望公式

一个经典xxs的题:

A班平均分为x分,B班平均分为y分

求A、B两个班的平均分

显而易见的:A、B班的平均分不能直接(x+y)/2

而是:(x*a+ y*b)/(x+y),其中a表示A班人数,b表示B班人数

期望也差不多。

友好的看一下全期望公式:

设 X 是一个离散型随机变量, 当 X = xi 时,随机变量 Y 可能包含多种情况 y1, y2,⋯, yk,随机变量 Y 的条件 数学期望为:

E(Y|X=x_i)=\sum ^{k}_{j=1}y_j × P(Y = y_j |X = x_i)

对于随机变量 X 有很多取值 x1, x2,⋯, xa,Y 有很多取值 y1, y2,⋯, yb。

全期望公式:

E(Y)=E(E(Y|X))

            =\sum ^{a}_{i=1}P(X = x_i)E(Y|X = x_i)

            = \sum^{a}_{i=1}P(X=x_i)\sum^{b}_{j=1}y_j*P(Y=y_j|X=x_i)

            =\sum^{a}_{i=1}\sum^{b}_{j=1}y_j*P(X=xi)*P(Y= y_i|X=x_i)

            =\sum^{a}_{i=1}\sum^{b}_{j=1}y_j×P(X=x_i,Y=y_j)

            =E(Y)

例如,一项工作由甲一个人完成,平均需要 4 小时,而乙有 0.4 的概率来帮忙,两个人完成平均只需要 3 小时。

若用 X 表示完成这项工作的人数,而 Y 表示完成的这项工作的期望时间(单位小时)

由于这项工作要么由一 个人完成, 要么由两个人完成,那么这项工作完成的期望时间

E(Y)=P(X=1)*E(Y|X=1)+P(X=2)*E(Y|X=2)=(1-0.4)*4-0.4*3=3.6

例题

「ABC184D」increment of coins

【题目描述】

袋子里原本有金币 A 枚、银币 B 枚、铜币 C 枚。

直到袋子中有一种硬币达到 100 枚之前,都会进行以下操作。

操作:每次都有 1 枚硬币被等概率地取出,然后向袋子中放入两枚相同的硬币。

求出操作次数的数学期望。

【输入格式】

一行三个整数 A,B,C(0≤A,B,C≤99,A+B+C≥1)。

【输出格式】

一行一个浮点数,为操作次数的数学期望。若与标准答案的误差不超过 10−6,则视为正确答案。

【样例 1 输入】

99 99 99

【样例 1 输出】

1.000000000

【样例 1 解释】

不论第一次操作取出哪种硬币,袋中都会出现 100 枚该种硬币。

【样例 2 输入】

98 99 99

【样例 2 输出】

1.331081081

【样例 3 输入】

0 0 1

【样例 3 输出】

99.000000000

 思路:用记忆化搜索,每种硬币从100往下搜索,期望就是

dfs(x+1,y,z)*x/(x+y+z)+dfs(x,y+1,z)*y/(x+y+z)+dfs(x,y,z+1)*z/(x+y+z);
//很好理解,三种概率对应的值的和

总代码为

#include<bits/stdc++.h>
using namespace std;

const int N=105;
int a,b,c;
double f[N][N][N];

double dfs(int x,int y,int z)
{
	if(x>=100||y>=100||z>=100) return 0;
	if(f[x][y][z]) return f[x][y][z];
	double t=1;
	t+=dfs(x+1,y,z)*x/(x+y+z);
	t+=dfs(x,y+1,z)*y/(x+y+z);
	t+=dfs(x,y,z+1)*z/(x+y+z);
	f[x][y][z]=t;
	return t;
}

int main()
{
	scanf("%d%d%d",&a,&b,&c);
	printf("%.8lf",dfs(a,b,c));
	return 0;
} 

  「ABC280E」Critical Hit

【题目描述】

这里有一个 n 滴血的怪物。每一次攻击你有 p% 的概率让它失去 2 滴血,有 (100−p)% 的概率让它失去 1 滴血。如果攻击过后怪物的血量 ≤0,它就死了。

你需要一直攻击怪物直到它死亡。输出攻击次数的期望对 998244353 取模的值。

【输入格式】

第一行为整数 n,p(1≤n≤2×105,0≤p≤100)

【输出格式】

输出答案。

【样例 1 输入】

3 10

【样例 1 输出】

229596204

【样例 2 输入】

5 100

【样例 2 输出】

3

【样例 3 输入】

280 59

【样例 3 输出】

567484387

 思路:dp[i]表示怪物还有i第血时的期望

每次向前看两个数并计算

关键代码:

dp[i]=(((dp[i-2]+1)*p+(dp[i-1]+1)*(100-p))%MOD)*828542813%MOD;//逆元防溢出
//循环范围:i:2~n

总代码为

#include<bits/stdc++.h>
using namespace std;

const long long MOD=998244353;
long long dp[200005];
int n,p;

int main()
{
	cin>>n>>p;
	dp[0]=0,dp[1]=1;
	for(int i=2;i<=n;i++)
		dp[i]=(((dp[i-2]+1)*p+(dp[i-1]+1)*(100-p))%MOD)*828542813%MOD;
	cout<<dp[n];
	return 0;
}

TYVJ P2002 扑克牌

Rainbow把一副扑克牌(54张)随机洗开,倒扣着放成一摞。然后Admin从上往下依次翻开每张牌,每翻开一张黑桃、红桃、梅花或者方块,就把它放到对应花色的堆里去。
Rainbow想问问Admin,得到A张黑桃、B张红桃、C张梅花、D张方块需要翻开的牌的张数的期望值E是多少?
特殊地,如果翻开的牌是大王或者小王,Admin将会把它作为某种花色的牌放入对应堆中,使得放入之后E的值尽可能小。
由于Admin和Rainbow还在玩扑克,所以这个程序就交给你来写了~

输入

输入仅由一行,包含四个用空格隔开的整数,A,B,C,D。

输出

输出需要翻开的牌数的期望值E,四舍五入保留3位小数。
如果不可能达到输入的状态,输出-1.000。

样例

样例输入1
样例输入1
1 2 3 4

样例输入2
15 15 15 15
样例输出1
样例输出1
16.393

样例输出2
-1.000

提示

对于100%的数据,0<=A,B,C,D<=15

想法和第一题类似

记忆化搜索+肝

重点代码:

    if(a<13) ans+=dfs(a+1,b,c,d,x,y)*(13-a)/cnt;
	if(b<13) ans+=dfs(a,b+1,c,d,x,y)*(13-b)/cnt;
	if(c<13) ans+=dfs(a,b,c+1,d,x,y)*(13-c)/cnt;
	if(d<13) ans+=dfs(a,b,c,d+1,x,y)*(13-d)/cnt;
	if(x==4) ans+=min(min(dfs(a,b,c,d,0,y),dfs(a,b,c,d,1,y)),min(dfs(a,b,c,d,2,y),dfs(a,b,c,d,3,y)))/cnt;
	if(y==4) ans+=min(min(dfs(a,b,c,d,x,0),dfs(a,b,c,d,x,1)),min(dfs(a,b,c,d,x,2),dfs(a,b,c,d,x,3)))/cnt;
//其实都还好,期望公式而已

 总代码

#include<bits/stdc++.h>
using namespace std;

const int N=15,M=5;
double f[N][N][N][N][M][M],ans;
bool v[N][N][N][N][M][M];
int A,B,C,D;

void get(int x,int &a,int &b,int &c,int &d)
{
	switch(x)
	{
		case 0:++a;return;
		case 1:++b;return;
		case 2:++c;return;
		case 3:++d;return;
	}
}

double dfs(int a,int b,int c,int d,int x,int y)
{
	if(v[a][b][c][d][x][y]) return f[a][b][c][d][x][y];
	v[a][b][c][d][x][y]=1;
	double &ans=f[a][b][c][d][x][y];
	ans=0;
	int _a=a,_b=b,_c=c,_d=d;
	get(x,_a,_b,_c,_d);get(y,_a,_b,_c,_d);
	if(_a>=A&&_b>=B&&_c>=C&&_d>=D) return 0;
	if(_a>A&&_b>B&&_c>C&&_d>D) return 0;
	int cnt=54-_a-_b-_c-_d;
	if(cnt<=0) return 11451419198;
	if(a<13) ans+=dfs(a+1,b,c,d,x,y)*(13-a)/cnt;
	if(b<13) ans+=dfs(a,b+1,c,d,x,y)*(13-b)/cnt;
	if(c<13) ans+=dfs(a,b,c+1,d,x,y)*(13-c)/cnt;
	if(d<13) ans+=dfs(a,b,c,d+1,x,y)*(13-d)/cnt;
	if(x==4) ans+=min(min(dfs(a,b,c,d,0,y),dfs(a,b,c,d,1,y)),min(dfs(a,b,c,d,2,y),dfs(a,b,c,d,3,y)))/cnt;
	if(y==4) ans+=min(min(dfs(a,b,c,d,x,0),dfs(a,b,c,d,x,1)),min(dfs(a,b,c,d,x,2),dfs(a,b,c,d,x,3)))/cnt;
	return ++ans;
}

int main()
{
	scanf("%d%d%d%d",&A,&B,&C,&D);
	ans=dfs(0,0,0,0,4,4);
	ans>60?puts("-1.000"):printf("%.3lf\n",ans);
	return 0;
}

结语

期望与概率真的很绕

题还是自己想一想,不要直接C

看不懂就反复看,拿出paper mouse追1832的精神

下期见!(不摆烂了,先复活一段时间)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值