【CodeForces】【148D】Bag of mice

概率DP

  kuangbin总结中的第9题

  啊……题目给的数据只有白鼠和黑鼠的数量,所以我们只能在这个上面做(gao)文(D)章(P)了……

  明显可以用两种老鼠的数量来作为状态= =

  我的WA做法:

    令f[i][j]表示从(w,b)轮流取老鼠一直到(i,j)【此时轮process取】两人一直不分胜负的概率,很明显(i,j)这个状态下赢的概率为 i / (i+j) ,那么总共赢的概率就是对所有(i,j),f[i][j]*i/(i+j)求和

    转移当然很简单啦~ f[i][j]只可能从f[i][j+3](两人一人抓了一只黑鼠,吓出来一只黑鼠)和f[i+1][j+2](两人一人抓了一只黑鼠,吓出来一只白鼠)两个状态转移过来。

    所以有 f[i][j]= f[i+1][j+2]*(j+2)/(i+j+3) *(j+1)/(i+j+2) *(i+1)/(i+j+1)  +  f[i][j+3]*(j+3)/(i+j+3) *(j+2)/(i+j+2) *(j+1)/(i+j+1);

    从f[n][m]=1.0逆推,每步累加ans即可

  我在第9个点就WA了……我猜是爆精度了……sigh,1e-9的精度伤不起啊。

 

  kuangbin的AC做法:

    将f[i][j]表示成轮到process抓时有 i 只白、j 只黑,她赢的概率。转移类似,但这样精度高(不像我还要另外累加?)(事实上我也没明白为什么……)反正精度会好许多……

 1 //CF 148D
 2 #include<cmath>
 3 #include<vector>
 4 #include<cstdio>
 5 #include<cstring>
 6 #include<cstdlib>
 7 #include<iostream>
 8 #include<algorithm>
 9 #define rep(i,n) for(int i=0;i<n;++i)
10 #define F(i,j,n) for(int i=j;i<=n;++i)
11 #define D(i,j,n) for(int i=j;i>=n;--i)
12 #define pb push_back
13 using namespace std;
14 int getint(){
15     int v=0,sign=1; char ch=getchar();
16     while(!isdigit(ch)) {if(ch=='-') sign=-1; ch=getchar();}
17     while(isdigit(ch))  {v=v*10+ch-'0'; ch=getchar();}
18     return v*sign;
19 }
20 const int N=1010,INF=~0u>>2;
21 const double eps=1e-10;
22 /*******************template********************/
23 double f[N][N];
24 int main(){
25     int n=getint(), m=getint();
26     double ans=0.0;
27     F(i,1,n) f[i][0]=1.0;
28     F(j,1,m) f[0][j]=0.0;
29     F(i,1,n) F(j,1,m){
30         f[i][j]=(double)i/(i+j);
31         if (j>=3) f[i][j]+=f[i][j-3]*j/(i+j)*(j-1)/(i+j-1)*(j-2)/(i+j-2);
32         if (j>=2) f[i][j]+=f[i-1][j-2]*i/(i+j)*j/(i+j-1)*(j-1)/(i+j-2);
33     }
34     printf("%.9lf\n",f[n][m]);
35     return 0;
36 }
View Code

 

posted @ 2015-02-26 18:54  Tunix  阅读(171)  评论(0编辑  收藏  举报