首页 > 代码库 > 【BZOJ1419】 Red is good [期望DP]

【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

Source

  这显然是一道简单的期望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

 

【BZOJ1419】 Red is good [期望DP]