codeforces 148D Bag of mice(機率dp)

題意:給你w個白色小鼠和b個黑色小鼠,把他們放到袋子裏,princess先取,dragon後取,princess取的時候從剩下的當當中任意取一個,dragon取得時候也是從剩下的時候任取一個,可是取完以後會隨機跳出來一個。取到每一個小鼠的機率是同樣的,跳出的也是同樣的。先取到白色的小鼠贏,問最後princess能贏的機率。spa

思路:機率dp,若是把princess能贏的分紅兩種狀況,那麼這個題就是遞推了,我是用記憶化搜索寫的。首先,用dp[i][j]表示袋子當中還有i個白色的,j個黑色的princess能取贏的機率。那麼有兩種狀況:code

1.這一步能取贏,那麼就是直接取到白色的,機率爲i/(i+j);blog

2.這一步取不贏,那麼當前必定是取到黑色的,由於最後要讓princess贏,因此,接着dragon也取不贏,如今還有一個問題是,跳出的小鼠的顏色,那麼又分爲兩種狀況:string

  1). 跳出的爲白色的。機率就是j/(i+j)*(j-1)/(i+j-1)*(i)/(i+j-2)*dp[i-1][j-2]it

  2). 跳出的位黑色的。機率就是j/(i+j)*(j-1)/(i+j-1)*(j-2)/(i+j-2)*dp[i][j-3]io

推到這裏基本上就出來了,剩下的邊界條件了。若是i==0,那麼機率必定是0,   若是i>0&&j==0那麼機率必定爲1.class

#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;

const int maxn = 1010;
double dp[maxn][maxn];
double dfs(int i, int j)
{
    if (i <= 0 || j < 0) return 0;
    if (i > 0 && j == 0) return dp[i][0] = 1;
    if (dp[i][j] != -1) return dp[i][j];
    double t1 = (double)i / (i + j);
    double t2 = (double)j / (i + j);
    dp[i][j] = t1;
    if (i + j > 2)
    {
        double t3 = dfs(i, j - 3) * (j - 1) / (i + j - 1) * (j - 2) / (i + j - 2);
        double t4 = dfs(i - 1, j - 2) * (j - 1) / (i + j - 1) * (i) / (i + j - 2);
        t2 *= (t3 + t4);
        dp[i][j] = t1 + t2;
    }
    return dp[i][j];
}
int main()
{
    int w, b;
    scanf("%d%d", &w, &b);
    //memset(dp, -1, sizeof(dp));
    for (int i = 0; i <= w; i++)
        for (int j = 0; j <= b; j++) 
            dp[i][j] = -1;
    printf("%.9f\n", dfs(w, b));

    return 0;
}
相關文章
相關標籤/搜索