引子
先来讲个故事······
话说在神奇的OI大陆上,有一只paper mouse
有一天,它去商场购物,正好是11.11,商店有活动
它很荣幸被选上给1832抽奖
在抽奖箱里,有3个篮蓝球,12个红球
paper mouse能抽3次
蒟蒻的paper mouse就疑惑了:抽到至少1个篮蓝球的概率是多少???
Answer:
总共有15个球
只抽到1个篮蓝球的概率是0.435165(很好理解吧,在4个
篮蓝球里取一个,再在11个红球里面取3个,总共是在15个里面取4个)
抽到2个篮蓝球的概率是0.079121
抽到3个篮蓝球的概率是0.002198
所以总概率就是三者之和,即0.435165+0.079121+0.002198=0.516484
我们也可以反过来分析:如果paper mouse运气爆棚,一个篮蓝球都没有抽到
那么其对立事件就一定会有至少一个篮蓝球
所以概率就是:1-1-0.483516=0.516484
也就是说,paper mouse有接近的概率给心爱的1832送上礼物······
概率
概率就是随机事件出现的可能性大小
For example,上面的故事里就涉及到概率
若某种事件重复了N次,其中A事件出现了M次,出现A事件的概率就是
同时,,用
表示
即:
1.1 条件概率与全概率
条件概率公式:
如果事件A发生的概率为P(A),事件B单独发生的概率为P(b)
若B必须在A发生之后发生,则B发生的概率就是条件概率,P(B)=P(A|b)=
(是不是还比较好理解?真正shit的才刚刚开始)
全概率公式:
如果事件 B1, B2,⋯, Bn 构成一个完整的样本空间,且两两互斥,P(Bi) > 0。 则对于任意事件 A 有:
,这就是全概率公式
思想就是: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={},
表示paper mouse表白了i次
所以paper mouse表白成功的概率高达0.3!(喜)
期望
炸裂的东西来了
先看看期望的定义
1.1 期望定义
如果随机变量只取得有限个值或无穷能按一定次序一一列出,其值域为一个或若干个有限或无限区间,这样的随 机变量称为离散型随机变量。
离散型随机变量的一切可能的取值 Xi 与对应的概率 P(Xi) 乘积之和称为该离散型随机变量的数学期望,记为 E(X) ,简称期望。
怎么样?是不是蛮有意思的?
换一种通俗但不精确的方式阐述一下(涉及下定义内容,非xxs请谨慎观看):
期望就是 某件事发生的概率集合中的每一个数 对其对应值的乘积 的和
一个普通骰子,众所周知有六面,对应1~6
每一面转到的概率就是 ,所以:
所以也可以这么说:
数学期望可以理解为某件事情大量发生之后的平均结果。
来个难点的:
设一张彩票为 2 元,每售 100000 张开奖,假每张彩票有一个对应的六位数号码,奖次如下:
- 安慰奖:奖励 4 元,中奖概率0.1
- 幸运奖:奖励 20 元,中奖概率 0.01
- 手气奖:奖励 200 元,中奖概率 0.001
- 一等奖:奖励 2000 元,中奖概率 0.0001
- 特等奖:奖励 20000 元,中奖概率 0.00001
那公司到底是亏还是赚呢?
我们来简单计算一下,对于每一位购买彩票的用户,公司可能支出为:
所以公司期望赚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
而是:,其中a表示A班人数,b表示B班人数
期望也差不多。
友好的看一下全期望公式:
设 X 是一个离散型随机变量, 当 X = xi 时,随机变量 Y 可能包含多种情况 y1, y2,⋯, yk,随机变量 Y 的条件 数学期望为:
对于随机变量 X 有很多取值 x1, x2,⋯, xa,Y 有很多取值 y1, y2,⋯, yb。
全期望公式:
例如,一项工作由甲一个人完成,平均需要 4 小时,而乙有 0.4 的概率来帮忙,两个人完成平均只需要 3 小时。
若用 X 表示完成这项工作的人数,而 Y 表示完成的这项工作的期望时间(单位小时)
由于这项工作要么由一 个人完成, 要么由两个人完成,那么这项工作完成的期望时间
例题
「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的精神
下期见!(不摆烂了,先复活一段时间)