CF148D Bag of mice

Link

Desprition

袋子里有 \(w\) 只白鼠和 \(b\) 只黑鼠 ,A和B轮流从袋子里抓,谁先抓到白色谁就赢。A每次随机抓一只,B每次随机抓完一只之后会有另一只随机老鼠跑出来。如果两个人都没有抓到白色则B赢。A先抓,问A赢的概率。

\(w,b\leq 1000\)

solution

概率 dp。

数据范围显然要求我们有个 \(O(n^2)\) 的做法。

\(f[i][j]\) 表示袋子里有 \(i\) 只白鼠 \(j\) 只黑鼠时 ,A赢得概率。

初始化:

  • \(f[i][1] = {i\over {i+1}}\) ,显然 \(A\) 只有在第一次抽到白鼠的时候才会赢,所以概率为 \(i\over{i+1}\)
  • \(f[i][0] = 1.0\) ,当袋子里只有白鼠时,\(A\) 第一个取必胜。

转移:

  • \(A\) 第一次就取到了白鼠 (欧皇),就直接赢了,概率为 \(i\over{i+j}\)

  • \(B\) 第一次就取到了白鼠,因为 \(B\) 一取到 白鼠 \(A\) 就输了,所以不用考虑这种情况。

  • \(A,B\) 都取到了黑鼠,跑出来是黑鼠,首先两个人都抽到黑鼠的概率为 \({j\over {i+j}}\times {j-1\over {i+j-1}}\) ,这时候在跑出一条黑鼠的概率为 \({j-2\over{i+j-2}}\) ,之后袋子里还剩下 \(i\) 只白鼠, \(j-3\) 只黑鼠,所以 \(A\) 赢得概率为 \(f[i][j-3]\) ,综上这种情况转移为 \(f[i][j] += {j\over {i+j}}\times {j-1\over {i+j-1}} \times {j-2\over{i+j-2}}\times f[i][j-3]\)

  • \(A,B\) 都取到黑鼠,跑出来一只白鼠,还是两个人都抽到黑鼠的概率为 \({j\over {i+j}}\times {j-1\over {i+j-1}}\) , 这时再跑出来一只白鼠的概率就是 \({i\over{i+j-2}}\) ,之后袋子里还剩下 \(i-1\) 只白鼠,\(j-2\) 只黑鼠,那么 \(A\) 赢得概率就为 \(f[i-1][j-2]\) ,综上转移为 \(f[i][j] += {j\over {i+j}}\times {j-1\over {i+j-1}}\times {i\over{i+j-2}} \times f[i-1][j-2]\)

在转移到时候要注意一下边界问题,数组不能出现负下标,然后这道题就做完了 QAQ。

Code

#include<iostream>
#include<cstdio>
#include<algorithm>
using namespace std;
int n,m;
double f[1010][1010];
inline int read()
{
	int s = 0,w = 1; char ch = getchar();
	while(ch < '0' || ch > '9'){if(ch == '-') w = -1; ch = getchar();}
	while(ch >= '0' && ch <= '9'){s = s * 10 + ch - '0'; ch = getchar();}
	return s * w;
}
int main()
{
	n = read(); m = read();
	for(int i = 1; i <= n; i++)
	{
		f[i][0] = 1.0;
		f[i][1] = 1.0 * i / (i+1);
	}
	for(int i = 1; i <= n; i++)
	{
		for(int j = 2; j <= m; j++)
		{
			f[i][j] = 1.0 * i / (i+j);
			if(j >= 3) f[i][j] += 1.0 * j / (i+j) * (j-1) / (i+j-1) * (j-2) / (i+j-2) * f[i][j-3];
			if(j >= 2) f[i][j] += 1.0 * j / (i+j) * (j-1) / (i+j-1) * i / (i+j-2) * f[i-1][j-2];
		}
	}
	printf("%.9lf",f[n][m]);
	return 0;
}

posted @ 2020-10-25 07:15  genshy  阅读(67)  评论(0编辑  收藏  举报