列表

详情


NC232848. 一袋小球

描述

D和P轮流从一个装有w个白球和b个黑球的袋子中轮流取小球,第一个取到白球的人获胜(所有小球除颜色外完全相同)。当袋子中没有小球时,D获胜。为了更容易获胜,每次D取小球时会故意多带出一个小球(带出的小球不算取出,带出每个小球的概率相同)。
所有小球取出或带出后不放回,求P先手时P获胜的概率。

输入描述

输入一行两个整数wb ()。

输出描述

输出一行一个实数,表示P获胜的概率。与答案的绝对或相对误差不超过即为正确。

示例1

输入:

1 3

输出:

0.500000000

说明:

P第一轮取到白球的概率为1/4,D第一轮取不到白球的概率为3/4 * 2/3 = 1/2。在D第一轮取不到白球的情况下,袋中剩下一黑一白两个小球,此时D带出白球时,D获胜,否则P获胜(概率为1/2 * 1/2 = 1/4)。故P获胜的概率为1/4 + 1/4 = 1/2。

示例2

输入:

5 5

输出:

0.658730159

原站题解

上次编辑到这里,代码来自缓存 点击恢复默认模板

C++(g++ 7.5.0) 解法, 执行用时: 38ms, 内存消耗: 32056K, 提交时间: 2023-04-20 12:00:23

#include <vector>
#include <iomanip>
#include <iostream>
#include <algorithm>
using namespace std;

#define endl '\n'
using LL=long long;
using LD=long double;
constexpr int N=1e3+10;
LD dp[N][N][2];

void solve() {
    int w,b;
    cin>>w>>b;

    for(int i=0;i<=w;i++) {
        for(int j=0;j<=b;j++) {
            LD pw=LD(i)/(i+j);
            LD pb=LD(j)/(i+j);
            
            if(i==0) dp[i][j][0]=0;
            else dp[i][j][0]=pw+(1-dp[i][j-1][1])*pb;

            if(i==0||i+j<=2) dp[i][j][1]=1;
            else {
                if(i) dp[i][j][1]+=pw;
                if(j>=2) dp[i][j][1]+=pb*LD(j-1)/(i+j-1)*(1-dp[i][j-2][0]);
                if(i&&j) dp[i][j][1]+=pb*LD(i)/(i+j-1)*(1-dp[i-1][j-1][0]);
            }
        }
    }
    cout<<fixed<<setprecision(12)<<dp[w][b][0];
}

int main() {
    ios::sync_with_stdio(0);
    cin.tie(nullptr);
    solve();
    return 0;
}

C++ 解法, 执行用时: 18ms, 内存消耗: 8232K, 提交时间: 2022-07-21 00:11:14

#include<bits/stdc++.h>
using namespace std;
const int N=1e3+5;
double f[N][N];
int w,b;
void solve(){
    cin>>w>>b;
    for(int i=1;i<=w;i++) f[i][0]=1;
    for(int i=1;i<=w;i++){
        for(int j=1;j<=b;j++){
            f[i][j]=1.0*i/(i+j);
            if(j>=3) f[i][j]+=1.0*j/(i+j)*(j-1)/(i+j-1)*(j-2)/(j+i-2)*f[i][j-3];
            if(j>=2) f[i][j]+=1.0*j/(i+j)*(j-1)/(i+j-1)*(i)/(j+i-2)*f[i-1][j-2];
        }
    }
    printf("%.10lf\n",f[w][b]);
}
int main(){
    solve();
}

上一题