初谈期望

之间就已经接触过了期望,但一直都不是很会用(考场上老是忘记),现在就讲讲基础的期望吧。

首先,需要掌握一定的概率知识,就是要知道如何求一件事发生的概率。

先声明,我们这里

p(x)  :  发生事件x的概率      pi   同理

E\left ( x \right ) : 发生事件x的期望      

xi   : 是个随机变量(通俗的讲就是因题目的需求而变的)

嗯,然后期望怎么算呢?

                                                                            E(X)=\sum xi*pi

举个栗子吧

假设有一个人,投进1分球(假设有)的概率是0.5,投进2分球的概率是0.4,投进3分球的概率是0.1,求出那个人投一次球得分的期望

解法:直接套上面的公式就行了,其中概率就是pi,几分球就是随机变量xi      

然后得分的期望就是0.5*1+0.4*2+0.1*3=1.6(期望不一定是整数,也有可能是负数)

所以得分的期望就是1.6

是不是很简单。

但这只是最最最最最最基础的。

下面讲一下我刚开始接触的那种:

就是假设有一种可乐(肥宅快乐水),瓶盖上有两种符号 ♂ 和  ♀ ,每次打开瓶盖都会等概率获得一种,求期望买几瓶可乐可以凑齐这两种符号。

解法:首先,这一题和上一题不同的是这一题有无限种可能性,就是可能一直拿到♂或♀,那怎么算呢,这不是扯淡吗?

先不要着急着走,这是可以求得的,随便说一句,千万不要用生活常识来理解信息学和数学。

首先,我们假设E(x)为已经得到了其中的x种符号,还要买几瓶可乐的期望。

那么很明显E(2) = 0

有了这个基础,后面的就方便多了

E(1)=0.5*E(1)+0.5*E(2) +1     就是每次买一瓶可乐,有0.5的概率会抽到和之前的相同,就是0.5*E(1),有0.5的概率会抽到另一种,就是0.5*E(2),最后加上1是因为多抽了一次嘛,所以期望次数就加一咯

整理一下可得

0.5*E(1)=0.5*E(2)+1 

因为E(2)=0

所以可得

E(1)=2

在继续推

E(0)=0.5*E(0)+0.5*E(1)+1

整理得

0.5*E(0)=0.5*E(1)+1

因为E(1)=2

所以

E(0)=4

这就是最后的答案(看解题一开始E的定义)

是不是很棒棒

那么再来一题

假设有一只仓鼠,它每天都有P的概率会死掉,问仓鼠的期望存活天数

(图侵删)                                       

解法:这题比起上一题就更加嘿嘿了,直接讲吧

E为仓鼠的期望存活天数

E=1+P*0+(1-P)*E      1就是期望天数加1,P*0就是它死了,所以期望天数对目前的贡献就是为0。为蛤右边还是E呢?因为对于这只仓鼠而言,它多活了一天,它死亡的概率不会变的(也就是说存活期望天数不会变,不会受到影响),所以这里还是E

最后化简就是

E=\frac{1}{P}  

注意!!P是概率

那么就差不多了吧……希望懂了…………

对了,再口胡一道题吧。

给出n,m还有一个长度为m的序列A,每次随机生成1~n的一个数,求得到A的每个前缀的期望次数。

解法:

这是一道自我感觉比较经典的题,我们可以把这个问题看作一个字符串问题,首先我们设E(X)为已经匹配了序列A的X位的期望次数,那么由上面已知的知识可知E(x)=\frac{E(x+1)+\sum E[j]+1}{n},整理得E(x+1)=nE(x)-n-\sum E(j),这就变成了一个递推式,然后我们就可以开心地打代码了。

上代码:

#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;
}

 

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值