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 }
时间: 2024-11-05 11:45:44