zoukankan      html  css  js  c++  java
  • Bzoj 2318 Spoj4060 game with probability Problem

    2318: Spoj4060 game with probability Problem

    Time Limit: 1 Sec  Memory Limit: 128 MB
    Submit: 524  Solved: 262
    [Submit][Status][Discuss]

    Description

    AliceBob在玩一个游戏。有n个石子在这里,AliceBob轮流投掷硬币,如果正面朝上,则从n个石子中取出一个石子,否则不做任何事。取到最后一颗石子的人胜利。Alice在投掷硬币时有p的概率投掷出他想投的一面,同样,Bobq的概率投掷出他相投的一面。

    现在Alice先手投掷硬币,假设他们都想赢得游戏,问你Alice胜利的概率为多少。

     

     

    Input

    第一行一个正整数t,表示数据组数。

    对于每组数据,一行三个数npq

     

     

    Output

    对于每组数据输出一行一个实数,表示Alice胜利的概率,保留6位小数。

     

     

    Sample Input

    1

    1 0.5 0.5


    Sample Output

    0.666667


    HINT

    数据范围:


    1<=t<=50


    0.5<=p,q<=0.99999999


    对于100%的数据 1<=n<=99999999

      一道无比有趣的概率题……

      我们设f[i]为当前有i张牌且我们当前所针对人物为先手的获胜概率,g[i]为后手获胜概率。

      那么,我们先考虑一下选择希望翻正面的概率的递推式。

        f[i]=p*g[i-1]+(1-p)*g[i]

      因为我们有p的几率将当前局面改为后手、场上有i-1张牌,1-p的几率将局面改为g[i]所以我们上述递推式正确的。g[i]也是如此。

        g[i]=q*f[i-1]+(1-q)*f[i]

      为什么这里变为q呢?因为当前我们希望翻正面一定是因为g[i-1]>f[i-1],而这个概率对于谁都是一样的,所以bob也一定是想要去翻正面,所以改为q。

      虽然这样我们好像还是无法推出来啊。所以我们要去解一下方程组,反正不就是一个二元一次吗?手解一下不就好了,应该不用高斯消元吧……

      至于希望翻反面,请读者自己思考,答案就在代码里(当然不是原始状态啦)。

      有意思的是虽然他的n很大,但是他并未对精度要求太高,所以我们只要等到他的精度卡到一定地步直接跳出就好了。

      我一开始是直接判断精度,但是貌似T了,所以看别人算到1000就行了……

     1  
     2 #include <iostream>
     3 #include <cstdlib>
     4 #include <cstdio>
     5 #include <cstring>
     6 #include <algorithm>
     7 #include <cmath>
     8 #include <queue>
     9 #include <map>
    10 #include <set>
    11 #include <vector>
    12 #define N 1005
    13 using namespace std;
    14 int t,n;
    15 double p,q,f[N],g[N];
    16 int main()
    17 {
    18     scanf("%d",&t);
    19 while(t--)
    20 {
    21     scanf("%d%lf%lf",&n,&p,&q);
    22     memset(f,0,sizeof(f));
    23     memset(g,0,sizeof(g));
    24     g[0]=1;
    25     n=min(n,1000);
    26     for(int i=1;i<=n;i++)
    27     {
    28         if(f[i-1]<g[i-1])
    29         {
    30             f[i]=(p*g[i-1]+(1.0-p)*q*f[i-1])/(p+q-p*q);
    31             g[i]=(q*f[i-1]+(1.0-q)*p*g[i-1])/(p+q-p*q); 
    32         }
    33         else
    34         {
    35             f[i]=(p*(1.0-q)*f[i-1]+(1.0-p)*g[i-1])/(1.0-p*q);
    36             g[i]=((1.0-q)*f[i-1]+q*(1.0-p)*g[i-1])/(1.0-p*q);
    37         }
    38          
    39     }
    40     printf("%.6lf
    ",f[n]);
    41 }
    42     return 0;
    43 }
    View Code

      

  • 相关阅读:
    IOS7 UI设计的十大准则
    IOS8-人机界面指南
    Android应用切换皮肤功能实现
    Android 打造自己的个性化应用(五):仿墨迹天气实现续--> 使用Ant实现zip/tar的压缩与解压
    Android 打造自己的个性化应用(四):仿墨迹天气实现-->自定义扩展名的zip格式的皮肤
    Android 打造自己的个性化应用(三):应用程序的插件化
    Android 打造自己的个性化应用(二):应用程序内置资源实现换肤功能
    Android 打造自己的个性化应用(一):应用程序换肤主流方式的分析与概述
    Android防止内存泄漏以及MAT的使用
    Android内存泄漏监测(MAT)及解决办法
  • 原文地址:https://www.cnblogs.com/liutianrui/p/7757680.html
Copyright © 2011-2022 走看看