B20J_1419_red is good_期望DP
题意:有R张红牌和B张黑牌,一张一张地翻牌,翻到红牌得到1美元,黑牌则付出1美元。可以随时停止翻牌,在最优策略下平均能得到多少钱。
分析:期望DP。
状态描述:f[i][j]表示当前有i张红牌,j张黑牌平均能够获得的钱数。
转移:考虑当前翻开的是什么牌。
f[i][j]=max{0,(f[i-1][j]+1)*i/(i+j)+(f[i][j-1]-1)*j/(i+j)}.
对最优策略的理解:如果当前获得钱为负数就没有必要转移了。
其他:1.题目要求截断保留6位小数。2.空间需要滚动优化。
代码
1 #include <stdio.h>
2 #include <string.h>
3 #include <algorithm>
4 using namespace std;
5 #define du double
6 #define eps 1e-8
7 du f[2][5010],ans;
8 int r,b;
9 int main()
10 {
11 scanf("%d%d",&r,&b);
12 for(int i=1;i<=r;i++)
13 {
14 f[i&1][0]=i;
15 for(int j=1;j<=b;j++)
16 {
17 f[i&1][j]=max(0.0,
18 (f[(i-1)&1][j]+1)*i/(1.0*(i+j))
19 +
20 (f[i&1][j-1]-1)*j/(1.0*(i+j)));
22 }
23 }
24 printf("%.6lf",max(0.0,f[r&1][b]-0.0000005));
25 }
26
27 /***************************************************************
28 Problem: 2453
29 User: 20170105
30 Language: C++
31 Result: Accepted
32 Time:432 ms
33 Memory:1040 kb
34 ****************************************************************/