「Codeforces 148D」Bag of mice

Posted hlw1

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了「Codeforces 148D」Bag of mice相关的知识,希望对你有一定的参考价值。

袋子里有 (w) 只白鼠和 (b) 只黑鼠 ,(A)(B) 轮流从袋子里抓,谁先抓到白色谁就赢。(A) 每次随机抓一只,(B) 每次随机抓完一只之后会有另一只随机老鼠跑出来。如果两个人都没有抓到白色则 (B) 赢。(A) 先抓,问 (A) 赢的概率。

Luogu

分析

不会概率 DP 。。。。。使用记忆化搜索。

我们记 (f[i][j]) 为当前还剩 (i) 个白鼠 (j) 个黑鼠 (A) 赢的概率。

(dfs(n, m))(n) 为当前白鼠个数, (m) 为当前黑鼠个数,如果 (n=0) ,那么显然 (A) 必输,否则如果 (m=0) ,那么 (A) 必赢。然后我们分情况讨论。先计算 (A) 抽到白鼠的概率为 (frac{n}{n+m}) ,然后考虑 (A) 抽到黑鼠的情况。首先, (A) 抽到黑鼠的概率为 (frac{m}{n+m}) ,如果 (B) 抽到白鼠,那么 (A) 赢的概率为 (0) ,而我们只需要计算 (A) 赢的概率,所以可以不用考虑 (B) 抽到白鼠。 (B) 抽到黑鼠的概率为 (frac{m-1}{n+m-1}) ,然后我们接着考虑跑掉的老鼠,它是黑鼠的概率为 (frac{m-2}{n+m-2}) ,是白鼠的概率为 (frac{n}{n+m-2}) ,再分别乘上 (dfs(n, m-3))(dfs(n-1, m-2)) ,注意到如果当前只有两只黑鼠,那么跑掉的老鼠只能是白鼠,我们判断一波就好了。

代码

#include <bits/stdc++.h>

#define N 1003

using namespace std;

int gi() {
    int x = 0, f = 1; char c = getchar();
    for ( ; !isdigit(c); c = getchar()) if (c == '-') f = -1;
    for ( ; isdigit(c); c = getchar()) x = x * 10 + (c ^ 48);
    return x * f;
}

double f[N][N];

double dfs(int n, int m) {
    if (!n) return 0.0;
    if (!m) return 1.0;
    if (f[n][m]) return f[n][m];
    double ans = 1.0 * n / (n + m);
    if (m == 2) ans += 1.0 * m / (n + m) * 1.0 * (m - 1) / (n + m - 1) * dfs(n - 1, m - 2);
    else if (m > 2) {
        double tmp = 1.0 * n / (n + m - 2) * dfs(n - 1, m - 2) + 1.0 * (m - 2) / (n + m - 2) * dfs(n, m - 3);
        ans += 1.0 * m / (n + m) * (m - 1) / (n + m - 1) * tmp;
    }
    return f[n][m] = ans;
}

int main() {
    int n = gi(), m = gi();
    printf("%.9f", dfs(n, m));
    return 0;
}

以上是关于「Codeforces 148D」Bag of mice的主要内容,如果未能解决你的问题,请参考以下文章

「Codeforces 148D」Bag of mice

Codeforces 148D Bag of mice:概率dp 记忆化搜索

Codeforces 148D 一袋老鼠 Bag of mice | 概率DP 水题

CF 148D D. Bag of mice (概率DP||数学期望)

Codeforces 105D Bag of mice

Bag of mice(概率DP)