cf-148D-概率dp

http://codeforces.com/problemset/problem/148/D

    n个白球m个黑球,公主和龙玩游戏,公主每次随机取一个球,龙每次随机取一个球,在龙取完之后袋子里的球会随机消失一个(消失的球不被算作任何一个人所取走的且后面不会再出现),谁先取到白球就算胜利,如果最后没有球了但是还没决出胜负那么龙就是获胜者,公主先手,问公主获胜的概率。

  f[i][j]表示轮到公主取的时候局面是i个白球j个黑球的概率,那么答案就是SUM{ f[i][j]*i/(i+j) }。

  边界是f[n][m]=1,由于要让游戏进行下去所以递推的时候双方都要取黑球(如果有一方取走白球那游戏结束没有下一个回合了,我们只需考虑公主面临的所有状态就好了),公主先取走一个黑球,龙取走一个黑球,消失一个白球/黑球之后对应的两个状态又是公主回合的状态了。

  

 1 #include<iostream>
 2 #include<cstring>
 3 #include<queue>
 4 #include<cstdio>
 5 #include<stack>
 6 #include<set>
 7 #include<map>
 8 #include<cmath>
 9 #include<ctime>
10 #include<time.h> 
11 #include<algorithm>
12 using namespace std;
13 #define mp make_pair
14 #define pb push_back
15 #define debug puts("debug")
16 #define LL long long 
17 #define pii pair<int,int>
18 #define eps 1e-9
19 #define inf 0x3f3f3f3f
20 
21 double f[1010][1010]; 
22 int main()
23 {
24     int t,i,j,k,n,m,u,v;
25     scanf("%d%d",&n,&m);
26     f[n][m]=1.0;
27     for(i=n;i>=1;--i){
28         for(j=m;j>=1;--j){
29             if(f[i][j]){
30                 double black=f[i][j]*((double)j/(i+j))*(double(j-1)/(i+j-1));
31                 if(i+j-2>0&&j-2>=0&&i-1>=0)
32                 f[i-1][j-2]+=black*(i)/(i+j-2);
33                 if(j-3>=0&&i+j-2>0)
34                 f[i][j-3]+=black*(j-2)/(i+j-2);
35             }
36         }
37     }
38     double ans=0;
39     for(i=0;i<=n;++i){
40         for(j=0;j<=m;++j){
41             if(i+j)
42             ans+=f[i][j]*i/(i+j);
43         }
44     }
45     
46     printf("%.9f\n",ans);
47     return 0; 
48 }

猜你喜欢

转载自www.cnblogs.com/zzqc/p/9021451.html