之间就已经接触过了期望,但一直都不是很会用(考场上老是忘记),现在就讲讲基础的期望吧。
首先,需要掌握一定的概率知识,就是要知道如何求一件事发生的概率。
先声明,我们这里
: 发生事件x的概率
同理
: 发生事件x的期望
: 是个随机变量(通俗的讲就是因题目的需求而变的)
嗯,然后期望怎么算呢?
举个栗子吧
假设有一个人,投进1分球(假设有)的概率是0.5,投进2分球的概率是0.4,投进3分球的概率是0.1,求出那个人投一次球得分的期望
解法:直接套上面的公式就行了,其中概率就是,几分球就是随机变量
然后得分的期望就是(期望不一定是整数,也有可能是负数)
所以得分的期望就是1.6
是不是很简单。
但这只是最最最最最最基础的。
下面讲一下我刚开始接触的那种:
就是假设有一种可乐(肥宅快乐水),瓶盖上有两种符号 ♂ 和 ♀ ,每次打开瓶盖都会等概率获得一种,求期望买几瓶可乐可以凑齐这两种符号。
解法:首先,这一题和上一题不同的是这一题有无限种可能性,就是可能一直拿到♂或♀,那怎么算呢,这不是扯淡吗?
先不要着急着走,这是可以求得的,随便说一句,千万不要用生活常识来理解信息学和数学。
首先,我们假设为已经得到了其中的x种符号,还要买几瓶可乐的期望。
那么很明显 = 0
有了这个基础,后面的就方便多了
就是每次买一瓶可乐,有0.5的概率会抽到和之前的相同,就是
,有0.5的概率会抽到另一种,就是
,最后加上1是因为多抽了一次嘛,所以期望次数就加一咯
整理一下可得
因为
所以可得
在继续推
整理得
因为
所以
这就是最后的答案(看解题一开始的定义)
是不是很棒棒
那么再来一题
假设有一只仓鼠,它每天都有P的概率会死掉,问仓鼠的期望存活天数
(图侵删)
解法:这题比起上一题就更加嘿嘿了,直接讲吧
为仓鼠的期望存活天数
1就是期望天数加1,
就是它死了,所以期望天数对目前的贡献就是为0。为蛤右边还是E呢?因为对于这只仓鼠而言,它多活了一天,它死亡的概率不会变的(也就是说存活期望天数不会变,不会受到影响),所以这里还是
最后化简就是
注意!!P是概率
那么就差不多了吧……希望懂了…………
对了,再口胡一道题吧。
给出n,m还有一个长度为m的序列A,每次随机生成1~n的一个数,求得到A的每个前缀的期望次数。
解法:
这是一道自我感觉比较经典的题,我们可以把这个问题看作一个字符串问题,首先我们设为已经匹配了序列A的X位的期望次数,那么由上面已知的知识可知
,整理得
,这就变成了一个递推式,然后我们就可以开心地打代码了。
上代码:
#include<bits/stdc++.h>
#define ll long long
using namespace std;
const int M = 1000005;
const int N = 105;
const int mod = 1e9 + 7;
int fail[M][N],n,m,a[M];
ll E[M];
void getfail(){ //KMP的升级版,相当于只有一个字符串的AC自动机
fail[0][a[1]]=1;
int k=0;
for(int i=1;i<=m;i++){
for(int j=1;j<=n;j++) fail[i][j]=fail[k][j];
fail[i][a[i+1]]=i+1;
k=fail[k][a[i+1]];
}
}
int main(){
scanf("%d%d",&n,&m);
for(int i=1;i<=m;i++) scanf("%d",&a[i]);
getfail();
for(int i=0;i<m;i++){
E[i+1]=((ll)n*E[i]-n+mod)%mod;//看上面
for(int j=1;j<=n;j++){
if(fail[i][j]!=i+1) E[i+1]=(E[i+1]-E[fail[i][j]]+mod)%mod;
}
}
for(int i=1;i<=m;i++) printf("%lld ",mod-E[i]);//注意正负
return 0;
}