CF148D Bag of mice (期望dp)

 

传送门

 

# 解题思路

​    ~~这怕是本蒟蒻第一个独立做出来的期望$dp$的题,发篇题解庆祝一下~~。首先,应该是能比较自然的想出状态设计$f[i][j][0/1]$ 表示当前还剩 $i$个白老鼠,$j$个黑老鼠,当前是$A/B$抓的概率。有个问题似乎因为当其中一个人抓到白老鼠时游戏就结束了,而在转移过程中比较难表示出来这个,但换状态的话比较难转移。所以要想一个办法,因为如果知道当前有$i$只白老鼠和$j$只黑老鼠的话,那么当前人获胜的概率可以$O(1)$的算出来,$p=\dfrac {i}{i+j}$。所以转移时只去转移那些抓黑老鼠的状态,而答案则在转移中更新就行了,具体转移和实现看代码。

 

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>

using namespace std;
const int MAXN = 1005;

int w,b;
double f[MAXN][MAXN][2],ans;

int main(){
    cin>>w>>b;int n=w+b;
    f[w][b][0]=1;if((w|b))ans=(double)w/n; //初值是还剩 w个白老鼠,b个黑老鼠,当前A取的概率是1。 
    for(int i=w;i>=0;i--)    
        for(int j=b-(i==w);j>=0;j--){
            f[i][j][0]=f[i+1][j+1][1]*((double)(j+1)/(i+j+2))*((double)(i+1)/(i+j+1));
            f[i][j][0]+=f[i][j+2][1]*((double)(j+2)/(i+j+2))*((double)(j+1)/(i+j+1));
            //f[i][j][0]可以从上一轮B拿走一只黑鼠扔掉一只黑鼠和拿走一只黑鼠和扔掉一只白鼠转移
                //但绝对不能从拿走一只白鼠转移,因为这样游戏就结束了。 
            if((i|j)) ans+=f[i][j][0]*((double)i/(i+j)); //每步加一次当前的答案。 
             f[i][j][1]=f[i][j+1][0]*((double)(j+1)/(i+j+1));
              //f[i][j][1]只能从上一轮A拿走一只黑鼠转移,因为拿走白鼠已经累计到答案里了 
        }
    printf("%.9lf",ans);
    return 0;
}
View Code

 



posted @ 2018-10-11 09:05  Monster_Qi  阅读(181)  评论(0编辑  收藏  举报