• 【BZOJ1419】 Red is good [期望DP]


    Red is good

    Time Limit: 10 Sec  Memory Limit: 64 MB
    [Submit][Status][Discuss]

    Description

      桌面上有R张红牌和B张黑牌,随机打乱顺序后放在桌面上,开始一张一张地翻牌,翻到红牌得到1美元,黑牌则付出1美元。可以随时停止翻牌,在最优策略下平均能得到多少钱。

    Input

      一行输入两个数R,B。

    Output

      在最优策略下平均能得到多少钱。输出答案时,小数点后第六位后的全部去掉,不要四舍五入。

    Sample Input

      5 1

    Sample Output

      4.166666

    HINT

      R,B<=5000

    Solution

      这显然是一道简单的期望DP。我们令 f[i][j] 表示剩下 i 个红牌和 j 个黑牌时的最优答案。那么显然:

      

      其中 i/(i+j) 和 j/(i+j) 表示选择到的概率。

      最后由于卡内存,我们滚动一下数组即可。

    Code

     1 #include<iostream>  
     2 #include<string>  
     3 #include<algorithm>  
     4 #include<cstdio>  
     5 #include<cstring>  
     6 #include<cstdlib>  
     7 #include<cmath>
     8 using namespace std; 
     9 typedef long long s64; 
    10  
    11 const int ONE = 5001;
    12 const int E6 = 1e6;
    13  
    14 int n,m;
    15 double f[2][5001];
    16  
    17 int get() 
    18 {
    19         int res=1,Q=1;  char c;
    20         while( (c=getchar())<48 || c>57)
    21         if(c=='-')Q=-1;
    22         if(Q) res=c-48; 
    23         while((c=getchar())>=48 && c<=57) 
    24         res=res*10+c-48; 
    25         return res*Q; 
    26 }
    27  
    28  
    29 int main()
    30 {
    31         n=get();    m=get();
    32         for(int i=0,A=0; i<=n; i++,A^=1)
    33         {
    34             f[A][0] = i;
    35             for(int j=0; j<=m; j++)
    36                 f[A][j] = max(0.0, (double)i/(i+j) * (f[A^1][j]+1) + (double)j/(i+j) * (f[A][j-1]-1) );
    37         }
    38         s64 record = floor(f[n&1][m] * E6);
    39         printf("%lld.%06lld", record/E6, record%E6);
    40 }
    View Code
  • 相关阅读:
    [转]SDRAM中的一些疑惑点
    [转]如何学习小波分析?
    [转]功率谱和频谱的区别、联系
    使用Vim为每一行自动编号
    [转]阿英 Matlab fftshift 详解
    [转]性噪比和相位失真
    神舟笔记本精盾K480N高频噪声消除方法
    Tips:verilog计数分频计算
    vim的列编辑操作
    【题解】 「CTSC2018」暴力写挂 点分治+虚树+树形dp LOJ2553
  • 原文地址:https://www.cnblogs.com/BearChild/p/6651440.html
Copyright © 2020-2023  润新知