【CodeForces148D】Bag of mice

题意

  dragon和princess玩一个游戏。开始的时候袋子里有w个白老鼠和b个黑老鼠。两个人轮流从袋子里面往外摸老鼠。谁先拿到白老鼠谁先获胜。dragon每次抓出一只老鼠,剩下老鼠里面都会有一只跳出袋子。princess则不会。 princess先抓。问princess赢得概率是多少。

分析

  简单的概率DP。我一看到两个人玩得这种游戏就习惯性的定义两个dp数组。

  f[i][j][0]为当前袋子里有i只白老鼠,j只黑老鼠时,princess赢得概率

  f[i][j][1]为当前袋子里有i只白老鼠,j只黑老鼠时,dragon赢得概率

  状态的转移也很好想

  f[i][j][0]=(1-f[i][j-1][1])*(j/(i+j))+i/(i+j).

  f[i][j][1]=(1-f[i-1][j-1][0])*j/(i+j)*i/(i+j-1)+(1-f[i][j-2][0])j/(i+j)(j-1)/(i+j-1)+i/(i+j)

  AC代码如下

  

 1 #include <cstdio>
 2 #include <cstring>
 3 #include <algorithm>
 4 #include <iostream>
 5 
 6 using namespace std;
 7 const int maxn=1000+100;
 8 int w,b;
 9 double f[maxn][maxn][3];
10 
11 int main(){
12     scanf("%d%d",&w,&b);
13     memset(f,0,sizeof(f));
14     f[0][0][0]=0;f[0][0][1]=1.0;
15     for(int i=1;i<=w;i++)
16         f[i][0][0]=f[i][0][1]=1.0;
17     for(int i=1;i<=b;i++)
18         f[0][i][1]=1.0;
19     for(int i=0;i<=w;i++){
20         for(int j=0;j<=b;j++){
21             if(j==0||i==0)
22                 continue;
23             if(j>=1){
24              f[i][j][0]=(1-f[i][j-1][1])*j/(i+j)+(double)i/(i+j);
25              if(i>=1)
26              f[i][j][1]=(1-f[i-1][j-1][0])*(j*i)/((i+j)*(i+j-1))+(double)i/(i+j);
27             }
28             if(j>=2)
29             f[i][j][1]+=(1-f[i][j-2][0])*(j*(j-1))/((i+j)*(i+j-1));
30         }
31     }
32     printf("%.9f",f[w][b][0]);
33 
34 return 0;
35 }
View Code

 然后我看网上大佬们一般一个数组就解决了。

 令f[i][j]为当前有i个白老鼠,j个黑老鼠时,princess先手,赢得概率。

 那么状态转移有几种可能性:

 1.princess直接拿到了白老鼠,赢得了游戏,概率为i/(i+j)

 2.princess拿到了黑老鼠,dragon拿到了黑老鼠,跳出来黑老鼠,概率为j/(i+j) *  (j-1)/(i+j-1) *  (j-2)/(i+j-2)

 3.princess拿到了黑老鼠,dragon拿到了黑老鼠,跳出来一只白老鼠,概率为j/(i+j) *  (j-1)/(i+j-1) *  i/(i+j-2)

AC代码如下

 1 #include <cstdio>
 2 #include <cstring>
 3 #include <algorithm>
 4 #include <iostream>
 5 
 6 using namespace std;
 7 const int maxn=1000+100;
 8 double f[maxn][maxn];
 9 int w,b;
10 int main(){
11     scanf("%d%d",&w,&b);
12     memset(f,0,sizeof(f));
13     for(int i=1;i<=w;i++)
14         f[i][0]=1.0;
15     for(int i=1;i<=b;i++)
16         f[0][i]=0.0;
17     f[0][0]=0;
18     for(int i=1;i<=w;i++){
19         for(int j=1;j<=b;j++){
20             f[i][j]+=(double)i/(i+j);
21             if(j>=3){
22                 f[i][j]+=(double)j/(i+j)*(double)(j-1)/(i+j-1)*(double)(j-2)/(i+j-2)*f[i][j-3];
23             }
24             if(j>=2){
25                 f[i][j]+=(double)j/(i+j)*(double)(j-1)/(i+j-1)*(double)i/(i+j-2)*f[i-1][j-2];
26             }
27         }
28     }
29     printf("%.9f\n",f[w][b]);
30 return 0;
31 }
View Code

 

posted @ 2018-05-27 17:10  蒟蒻LQL  阅读(247)  评论(0编辑  收藏  举报