CF148D Bag of mice

Link

Desprition

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

(w,bleq 1000)

solution

概率 dp。

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

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

初始化:

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

转移:

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

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

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

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

原文地址:https://www.cnblogs.com/genshy/p/13871873.html