题意:
袋子里有w个白球b个黑球,现在两个人轮流每次取一个球(不放回),先取到白球的获胜,当后手取走一个球时,袋子里的球会随机的漏掉一个,问先手获胜的概率。
分析:
dp[i][j]表示袋子中i个白球j个黑球,先手取获胜的概率。
有四种情况
先手取到白球,获胜概率1.0*i/(i+j);
后手取到白球,先手输
前两次都取到黑球,漏掉一个黑球,转移到dp[i][j-3]
前两次都取到黑球,漏掉一个白球,转移到dp[i-1][j-2]
#include <map> #include <set> #include <list> #include <cmath> #include <queue> #include <stack> #include <cstdio> #include <vector> #include <string> #include <cctype> #include <complex> #include <cassert> #include <utility> #include <cstring> #include <cstdlib> #include <iostream> #include <algorithm> using namespace std; typedef pair<int,int> PII; typedef long long ll; #define lson l,m,rt<<1 #define pi acos(-1.0) #define rson m+1,r,rt<<11 #define All 1,N,1 #define read freopen("in.txt", "r", stdin) const ll INFll = 0x3f3f3f3f3f3f3f3fLL; const int INF= 0x7ffffff; const int mod = 1000000007; int w,b; double dp[1001][1001]; void solve(){ memset(dp,0,sizeof(dp)); for(int i=1;i<=w;++i) dp[i][0]=1;//只剩白球,必胜 for(int i=1;i<=w;++i) for(int j=1;j<=b;++j){ dp[i][j]=1.0*i/(i+j); if(j>=3) dp[i][j]+=dp[i][j-3]*1.0*j/(i+j)*(j-1)/(i+j-1)*(j-2)/(i+j-2); if(i>=1&&j>=2) dp[i][j]+=dp[i-1][j-2]*1.0*j/(i+j)*(j-1)/(i+j-1)*i/(i+j-2); } printf("%.9lf\n",dp[w][b]); } int main() { while(~scanf("%d%d",&w,&b)){ solve(); } return 0; }
时间: 2024-10-14 04:43:33