zoukankan      html  css  js  c++  java
  • UVA11427玩纸牌(全概率+递推)

    题意:
          一个人玩纸牌游戏,他每天最多玩n局,枚举获胜的概率是a/b,每天玩牌只要获胜概率达到p,那么他今天就不玩了,明天接着玩,如果有一天他的概率没有达到p,(没有达到p的话他今天一定是玩了n次),那么他以后就在也不玩了,问题是在平均的情况下,他能玩多少个晚上的牌?


    思路:
          我们可以先算他只玩一天就失败了的概率,P[i][j]表示玩了i次,赢了j次,当
    j/i<=p的时候,根据全概率公式,P[i][j] = P[i-1][j]*(1-p)+P[i-1][j-1]*p前面是输了后面是赢了,端点值是P[0][0] = 1 ,P[0][1] = 0,其他部分全都是0,记得要把其他部分清成0,因为更新是不连续的,这样之后只玩一天的概率等于Q = P[n][0] + P[n][1] +.....
    这样答案就是(期望)
    玩一天 1 * Q
    玩两天 2 * Q(1-Q)
    玩三天 3 * Q(1-Q)^2
    ......
    化简后 Ans = 1 / Q;
    说下化简的方法吧,有两种
    (1)
       a 令s = EX/Q = 1+2(1-Q)+3(1-Q)^2+4(1-Q)^3+...

       b     (1-Q)s = (1-Q)+2(1-Q)^2+3(1-Q)^3+....
    a - b得到
    EX = Qs = 1+(1-Q)+(1-Q)^2+(1-Q)^3+..=1/Q


    (2)
    设数学期望为e天,把情况分为两类,第一天晚上出头丧气概率Q期望1,第一天晚上兴高采烈,概率(1-Q)期望e + 1,解得 e = Q * 1 + (1 - Q) * (e + 1) => e = 1/Q;




    #include<stdio.h>
    #include<string.h>


    double P[105][105];


    int main ()
    {
       int n ,a ,b ,i ,j;
       int t ,cas = 1;
       scanf("%d" ,&t);
       while(t--)
       {
          scanf("%d/%d%d" ,&a ,&b ,&n);
          double p = a * 1.0 / b;
          memset(P ,0 ,sizeof(P));
          P[0][0] = 1 ,P[0][1] = 0;
          for(i = 1 ;i <= n ;i ++)
          for(j = 0 ;j * b <= i * a ;j ++)
          {
             P[i][j] = P[i-1][j] * (1 - p) ;
             if(j >= 1)P[i][j] +=  P[i-1][j-1] * p;
          }
          double Ans = 0;
          for(j = 0 ;j * b <= n * a ;j ++)
          Ans += P[n][j];
          printf("Case #%d: %d " ,cas ++ ,(int)(1 / Ans));
       }
       return 0;
    }
       



  • 相关阅读:
    YbtOJ#573后缀表达【二分图匹配】
    CF605EIntergalaxy Trips【期望dp】
    YbtOJ#482爬上山顶【凸壳,链表】
    AT4996[AGC034F]RNG and XOR【FWT,生成函数】
    YbtOJ#903染色方案【拉格朗日插值,NTT,分治】
    YbtOJ#832鸽子饲养【凸包,Floyd】
    YbtOJ#463序列划分【二分答案,线段树,dp】
    CF618FDouble Knapsack【结论】
    P3214[HNOI2011]卡农【dp】
    YbtOJ#526折纸游戏【二分,hash】
  • 原文地址:https://www.cnblogs.com/csnd/p/12062552.html
Copyright © 2011-2022 走看看