• ACMICPC Live Archive 6204 Poker End Games


    概率题

    题意:输入case数,每组case两个数字,表示A的点数和B的点数,他们玩游戏,每个人赢的概率都是0.5。输的人要将自己的一部分点数给对方,给的点数是min(na,nb)。例如na=3,nb=2

    如果A赢了,B要给2点给A,即全部给完。如果B赢了,A要给2点给B,A变为1,B变为4。一个人的点数为0,那么游戏结束了。题目要你输出两个数学期望,第一个是,这个游戏要结束,要玩多少局的数学期望,另一个是A赢的概率

    这题一开始看觉得是期望DP,后来想想也可以不写DP,能把状态表达出来即可。

    设一个状态(n,m,c)表示A现在的点数是n,B的点数是m,已经玩了c局。那么游戏结束的状态就是(n,0,c)或者(0,m,c)

    而玩了c局,游戏结束,这个概率是多少,就是(0.5)^c , 因为每次玩无论怎样概率都是0.5

    而这个游戏是可以无限玩下去的(这个很容易想到,其中sample2就可以无限玩下去),所以算这个数学期望和概率是没有尽头的,但是输出说了,精确到10^-5,当游戏局数很大是,不会再对数学期望和概率产生大的影响,在精度范围内

    所以搜索的时候,可以限制深度,即设定一个局数,超过了这个局数就返回不要继续算下去

    而每到游戏结束的时候,就可以计算数学期望和概率

    数学期望 = sum(xi*pi)

    概率 = sum(pi)

    #include <cstdio>
    #include <cstring>
    #define LIM 40
    #define min(a,b) ((a)<(b)?(a):(b))
    
    double EX[2];
    
    double cal(int c)
    {
       double ans = 1;
       for(int i=1; i<=c; i++)
          ans *= 0.5;
       return ans;
    }
    
    void dfs(int n ,int m , int c)
    {
       if(c > LIM) return ;  //限深度搜索
       if( n==0 || m==0) //游戏结束
       {
          double p = cal(c);
          EX[0] += c*p;
          if(m==0) EX[1] += p;
          return ;
       }
       int res = min(n,m);
       dfs(n-res , m+res , c+1);
       dfs(n+res , m-res , c+1);
    }
    
    int main()
    {
       int T;
       scanf("%d",&T);
       for(int t=1; t<=T; t++)
       {
          int n,m;
          scanf("%d%d",&n,&m);
          EX[0]=EX[1]=0;
          dfs(n,m,0);
          printf("Case %d: %.6lf %.6lf\n",t,EX[0],EX[1]);
       }
       return 0;
    }
  • 相关阅读:
    PHP 时间转换Unix 时间戳
    PHP中include()与require()的区别
    PHP substr_replace() 函数
    写了个jQuery无缝滚动小插件
    Orchard代码学习笔记 1. 入口
    也作一下装配脑袋的Expression习题
    [转]IIS7.5中神秘的ApplicationPoolIdentity
    Spring.net AOP异常记入单独日志文件
    [源码学习]Razor在VS调试配置
    [备忘]WPF的Colors类
  • 原文地址:https://www.cnblogs.com/scau20110726/p/3043740.html
Copyright © 2020-2023  润新知