• cf 148D 概率DP


    题意:
    原来袋子里有w只白鼠和b只黑鼠
    龙和王妃轮流从袋子里抓老鼠。谁先抓到白色老师谁就赢。
    王妃每次抓一只老鼠,龙每次抓完一只老鼠之后会有一只老鼠跑出来。
    每次抓老鼠和跑出来的老鼠都是随机的。
    如果两个人都没有抓到白色老鼠则龙赢。王妃先抓。
    问王妃赢的概率。
    解析:
    设dp[i][j]表示现在轮到王妃抓时有i只白鼠,j只黑鼠,王妃赢的概率
    明显 dp[0][j]=0,0<=j<=b;因为没有白色老鼠了
          dp[i][0]=1,1<=i<=w;因为都是白色老鼠,抓一次肯定赢了。
          dp[i][j]可以转化成下列四种状态:
          1、王妃抓到一只白鼠,则王妃赢了,概率为i/(i+j);
          2、王妃抓到一只黑鼠,龙抓到一只白色,则王妃输了,概率为j/(i+j)*i/(i+j-1).
          3、王妃抓到一只黑鼠,龙抓到一只黑鼠,跑出来一只黑鼠,则转移到dp[i][j-3]。
          概率为j/(i+j)*(j-1)/(i+j-1)*(j-2)/(i+j-2);
          4、王妃抓到一只黑鼠,龙抓到一只黑鼠,跑出来一只白鼠,则转移到dp[i-1][j-2].
          概率为j/(i+j)*(j-1)/(i+j-1)*i/(i+j-2);
          当然后面两种情况要保证合法,即第三种情况要至少3只黑鼠,第四种情况要至少2只白鼠

    代码如下:

     1 #include<iostream>
     2 #include<stdio.h>
     3 #include<algorithm>
     4 #include<iomanip>
     5 #include<cmath>
     6 #include<cstring>
     7 #include<vector>
     8 #define ll __int64
     9 #define pi acos(-1.0)
    10 #define MAX 50000
    11 using namespace std;
    12 double dp[1001][1001];
    13 int main(){
    14     int w,b,i,j;
    15     while(cin>>w>>b){
    16         for(i=1;i<=w;i++) dp[i][0]=1;
    17         for(i=0;i<=b;i++) dp[0][i]=0;
    18         for(i=1;i<=w;i++)
    19         for(j=1;j<=b;j++){
    20             dp[i][j]=1.0*i/(i+j);
    21             if(j>=3)
    22                 dp[i][j]+=1.0*j/(i+j)*(j-1)/(i+j-1)*(j-2)/(i+j-2)*dp[i][j-3];
    23             if(j>=2)
    24                 dp[i][j]+=1.0*j/(i+j)*(j-1)/(i+j-1)*i/(i+j-2)*dp[i-1][j-2];
    25         }
    26         printf("%.9lf
    ",dp[w][b]);
    27      }
    28     return 0;
    29 }
    View Code
  • 相关阅读:
    进程间通讯,线程间通讯
    进程与线程
    学习自测6.0
    学习自测5.0
    学习自测4.0
    学习自测3.0
    学习自测2.0
    学习自测1.0
    PS中怎么复制某个图层的效果?
    初学前端犯下的错误(用于反省)
  • 原文地址:https://www.cnblogs.com/xin-hua/p/3250511.html
Copyright © 2020-2023  润新知