ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

【dp选讲】浅谈概率dp

2021-11-14 09:00:51  阅读:155  来源: 互联网

标签:老鼠 概率 frac 浅谈 int 选讲 include dp


【dp选讲】概率与期望

说在前面

如果您此前还没有了解过任何有关概率的内容的话,请先自行学习概率和期望的相关定理,然后再食用本博客。

概率选题

注:概率和期望一般都是计算题,所以本博客仅从解题的角度向您展示概率和期望,具体做题的时候还是有一点思考难度的,但是一般比较统一。

CF148D

题目大意:有两个人往袋子里面抓老鼠,老鼠分为两类,一类是白老鼠,一类是黑老鼠,获胜规则是谁先抓到白老鼠谁就获胜。A抓老鼠的时候会附带着有一只老鼠溜出袋子,而B不会。如果最后是A抓到白老鼠或老鼠都跑光了,A也获胜,请问B获胜的概率是多少。输入:N只白老鼠和M只黑老鼠。

分析:

设 $$dp[i][j]$$ 为袋子里面有 i 只白老鼠和 j 只黑老鼠时的轮到B的获胜概率。

初始化:$$dp[0][j]=0$$ ,$$dp[i][0]=1$$,意思分别是:如果一只白老鼠都没有的话,就必输无疑;如果没有黑老鼠,反而全是白老鼠的话,那就必胜无疑。

先考虑B在当前状态下一次就抓到白老鼠的欧皇行为:

\[概率为:\frac{i}{i+j} \]

接着思考B拿到黑老鼠,而A拿到白老鼠的非酋行为:

\[概率为:\frac{j}{i+j}*\frac{i}{i+j-1} \]

【注:这是个分布事件,第一步是B非酋拿黑摆烂,第二步才是A欧皇拿白。】

第三种:B抓到黑老鼠,A也抓到黑老鼠,最后又跑出一只黑老鼠,此时的概率是:

\[\frac{j}{i+j}*\frac{j-1}{i+j-1}*\frac{j-2}{i+j-2} \]

上面这种情况可以转移到\(dp[i][j-3]\).

第四种:依旧是两人抓到黑老鼠,但是跑出来的是白老鼠,此时的概率为:

\[\frac{j}{i+j}*\frac{j-1}{i+j-1}*\frac{i}{i+j-2} \]

可转移到\(dp[i-1][j-2]\).

根据以上式子,dp转移即可。

#include<iostream>
#include<cstdio>
#define Maxn 5000 
using namespace std;
typedef double db;
int n,m;
db dp[Maxn][Maxn];
int main() {
	scanf("%d%d",&n,&m);
	for(int i=1;i<=n;i++) dp[i][0]=1;
	for(int j=1;j<=m;j++) dp[0][j]=0;
	for(int i=1;i<=n;i++) {
		for(int j=1;j<=m;j++) {
			dp[i][j]+=(db)i/(i+j);
			if(j>=3) 
				dp[i][j]+=(db)j/(i+j)*(j-1)/(i+j-1)*(j-2)/(i+j-2)*dp[i][j-3];
			if(j>=2) 
				dp[i][j]+=(db)j/(i+j)*(j-1)/(i+j-1)*i/(i+j-2)*dp[i-1][j-2];
		}
	}
	printf("%.9lf",dp[n][m]);
	return 0;
}  

[Scout YYF I][http://poj.org/problem?id=3744]

题目大意:在一个数轴上,有n个雷。一开始,你在原点,现在,你有p的概率走一步,有(1-p)的概率走两步,请问你有多大的概率可以安全通过雷阵?

分析:

直接算概率是不好求的,我们不如利用容斥原理,求出我们必定踩雷的概率(真非酋才能完成的壮举),最后用1减去即可。

于是乎,我们可以逐步求解,求出我们踩第一个雷的概率,接着是第二个雷的概率,以此类推。

很自然地,我们列出转移方程式:

\[dp[i]=p*dp[i-1]+(1-p)*dp[i-2] \]

但是!这是一道多测题,单测都是极限的\(10^9\)​了,线性递推肯定不可行,我们考虑优化。

仔细思考——嗯,这道题是不是有点似曾相识?看起来有点像斐波那契的递推式不是吗?那么这道题也许可以用矩阵乘法来优化。

于是,我们能列出这么一个矩阵的递推式:

\[p 1-p\\ 1 0 \]

幂次方取得是每一段的长度。

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#define Maxn 20000000
using namespace std;
typedef double db;
db p;
int n,pos[Maxn];
struct Matrix{
	double mat[2][2];
	void clear() {memset(mat,0,sizeof(mat));}
	void idenaty() {clear();for(int i=0;i<2;i++)mat[i][i]=1;}
};
Matrix mul(Matrix a,Matrix b) {
	Matrix res;
	res.clear();
	for(int i=0;i<2;i++) {
		for(int j=0;j<2;j++) {
			res.mat[i][j]=0;
			for(int k=0;k<2;k++) {
				res.mat[i][j]+=a.mat[i][k]*b.mat[k][j];
			}
		}
	}
	return res;
}
Matrix power(Matrix x,int p) {
	Matrix res;
	res.idenaty();
	Matrix base=x;
	while(p) {
		if(p&1) res=mul(res,base); 
		base=mul(base,base);
		p>>=1;
	}
	return res;
}
int main() {
	while(scanf("%d%lf",&n,&p)!=EOF) {
		for(int i=1;i<=n;i++) 
			scanf("%d",&pos[i]);
		db ans=1;
		sort(pos+1,pos+n+1);
		Matrix a;
		a.clear();
		a.mat[0][0]=p;a.mat[0][1]=1-p;
		a.mat[1][0]=1;a.mat[1][1]=0;
		Matrix ret;
		ret.clear();
		ret=power(a,pos[1]-1);	
		ans*=(1-ret.mat[0][0]);
		for(int i=2;i<=n;i++) {
			if(pos[i]==pos[i-1]) {continue;}
			ret.clear();
			ret=power(a,pos[i]-pos[i-1]-1);
			ans*=(1-ret.mat[0][0]);
		}
		printf("%.7lf\n",ans);
	}
	return 0;
}

标签:老鼠,概率,frac,浅谈,int,选讲,include,dp
来源: https://www.cnblogs.com/lxxwxxxxx/p/15550670.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有