您的位置:首页 > 其它

Light OJ 1050 - Marbles(概率DP)

2015-10-28 09:00 246 查看
题目大意:

一个包裹里有蓝色和红色的弹珠,在这个包裹里有奇数个弹珠,你先走, 你先从背包里随机的拿走一个弹珠,拿走每个弹珠的可能性是一样的。然后Jim从背包里拿走一个蓝色的弹珠,如果没有蓝色的弹珠让Jim拿走,那么Jim赢,如果最终从包裹里移走的是蓝的弹珠,那么你赢,否则Jim赢。给你蓝色和红的背包的里弹珠的个数,求赢的概率。

dp[R][B] 代表 R个红球, B个白球的时候赢得概率。当遇到 (R+B)%2 == 0 得时候直接 dp[R][B] = dp[R][B-1]就OK了。
这里采用的是记忆化搜索,所以用起来比较方便。

==============================================================================================================

#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
#include<cmath>
#include<queue>
#include<vector>
#include<map>
using namespace std;
typedef long long LL;
const int INF = 1e9+7;
const int MAXN = 555;
double dp[MAXN][MAXN];

double DFS(int R,int B)
{
if(dp[R][B] != -1)
return dp[R][B];
if(R >= B || B == 0)
return dp[R][B] = 0;
if(R == 0)
return dp[R][B] = 1;
double k = 1.0/(R + B);
if( (R+B)%2 )
dp[R][B] =  1.0*R*k*DFS(R-1,B) + 1.0*B*k*DFS(R, B-1);
else
dp[R][B] = DFS(R, B-1);

return dp[R][B];
}

int main()
{
int T, cas = 1, n, R, B;
for(int i=0; i<=500; i++)
for(int j=0; j<=500; j++)
dp[i][j] = dp[i][j] = -1;

scanf("%d", &T);
while(T --)
{
scanf("%d %d", &R, &B);

printf("Case %d: %.9lf\n",cas ++, DFS(R, B) );
}

return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: