codeforces 148D D. Bag of mice(概率dp)

本文解析了 Codeforces 148D 题目的解题思路,通过定义状态 dp[i][j] 来表示第 i 次取老鼠时剩余 j 只黑老鼠的概率,并详细说明了状态转移方程。最后提供了 AC 代码。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

题目链接:

codeforces 148D


题目大意:

给出w只白老鼠,b只黑老鼠,公主和龙轮流取老鼠,公主先手,龙取老鼠时会吓跑一只老鼠,先取出白老鼠的人赢,如果没人取到白老鼠,那么龙赢。问公主赢的概率。


题目分析:

  • 首先定义状态dp[i][j]表示第i次取老鼠时剩余黑老鼠为j的概率。
  • 那么最后结果就是
    ij=0bdp[i][j]
  • 那么怎么转移呢?分两种情况
    • i&1 :
      dp[i][j]=dp[i1][j+1]j+1sumi1
    • else:
      dp[i][j]=dp[i1][j+1](j+1)(sumi1j1)sumi1sumi11
  • 然后就是注意边界情况了,因为double值在边界情况上会出现很多情况,具体特判见代码

AC代码:

#include <iostream>
#include <cstdio>
#include <algorithm>
#include <cstring>
#define MAX 1007

using namespace std;

double dp[MAX][MAX];
int w,b,sum;

void calc ( int x )
{
    sum = x+x/2;
    sum = w+b-sum;
}

int main ( )
{
    while ( ~scanf ( "%d%d" , &w , &b ) )
    {
        if ( w == 0 )
        {
            puts ("0.0000000000" );
            continue;
        }
        memset ( dp , 0 ,sizeof ( dp ) );
        dp[0][b] = 1.0;
        for ( int i = 1 ; i <= b; i++ )
        {
            calc ( i-1 );
            for ( int j = 0; j <= b ; j++ )
            {
                dp[i][j] = 0;
                if ( i&1 )
                    dp[i][j] = dp[i-1][j+1]*((j+1)*1.0/(sum*1.0));
                else 
                {
                    double x = (j+1)*(j+2)*1.0/(sum*(sum-1)*1.0);
                    dp[i][j] += dp[i-1][j+2]*x;
                    x = (j+1)*(sum-1-j)*1.0/(sum*(sum-1)*1.0);
                    dp[i][j] += dp[i-1][j+1]*x;
                }
            }
        }
        double ans = 0;
        for ( int i = 0 ; i <= b ; i += 2 )
            for ( int j = 0 ; j <= b ; j++ )
            {
                calc ( i );
                if ( sum == 0 || sum < j  ) continue;
                //cout << dp[i][j] << " " <<  ans << endl;
                ans += dp[i][j]*((sum-j) *1.0/(sum*1.0));
            }
        printf ( "%.10lf\n" , ans );
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值