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

来源:互联网 发布:windows 2003 64 iso 编辑:程序博客网 时间:2024/05/20 02:28

题目链接:

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 1007using 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 );    }}
0 0
原创粉丝点击