zoukankan      html  css  js  c++  java
  • 【期望DP】BZOJ2318-[Spoj4060]Game with probability Problem

    【题目大意】

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

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

    【思路】

    不会23333详细题解看这里:

    详细的一些细节我放在注释里面了w

     1 #include<iostream> 
     2 #include<cstdio>
     3 #include<cstring>
     4 #include<iostream>
     5 #include<algorithm>
     6 using namespace std;
     7 const int MAXN=1000+5;
     8 double f[MAXN],g[MAXN],p,q;
     9 
    10 void solve()
    11 {
    12     int n;
    13     scanf("%d",&n);
    14     n=min(n,1000);
    15     //由于n很大的时候,概率几乎不再发生改变,则只需要取和1000中较小的即可 
    16     scanf("%lf%lf",&p,&q); 
    17     f[0]=0,g[0]=1;
    18     for(int i=1;i<=n;i++)
    19     {
    20         if(f[i-1]>g[i-1])p=1-p,q=1-q;
    21         //这里p和q表示的含义与题意不同,含义为当前投掷出正面朝上情况的概率
    22         //如果还剩i-1个石头时,A先手更有利,则在还是i个石头的时候,A希望B拿掉当前石头,B也希望A拿掉,故均希望反面向上。
    23         //这种情况下,正面朝上的概率就是1-p/1-q 
    24         //如果还剩i-1个石头时,A后手更有利,则两个人都希望自己能选,正面朝上的概率就是p/q 
    25         f[i]=(p*g[i-1]+(1-p)*q*f[i-1])/(1-(1-p)*(1-q));
    26         g[i]=(q*f[i-1]+(1-q)*p*g[i-1])/(1-(1-p)*(1-q));
    27         if(f[i-1]>g[i-1])p=1-p,q=1-q;
    28     }
    29     printf("%.6lf
    ",f[n]);
    30 }
    31 
    32 int main()
    33 {
    34     int T;
    35     scanf("%d",&T);
    36     while (T--) solve();
    37     return 0;
    38 }
  • 相关阅读:
    C++ const用于iterator
    C++实现类似python中的字符串split函数
    简单地解释overwrite
    ubuntu16.04 新安装的系统启动ssh服务
    强化学习7日打卡营-世界冠军带你从零实践--基于表格型方法的 RL
    spark-遇到问题小结
    Spark 读写hive 表
    spark-shell 显示乱码
    机器学习-GBDT和XGboost
    链表
  • 原文地址:https://www.cnblogs.com/iiyiyi/p/5779710.html
Copyright © 2011-2022 走看看