Description
桌面上有R张红牌和B张黑牌,随机打乱顺序后放在桌面上,开始一张一张地翻牌,翻到红牌得到1美元,黑牌则付出1美元。可以随时停止翻牌,在最优策略下平均能得到多少钱。
Input
一行输入两个数R,B,其值在0到5000之间
Output
在最优策略下平均能得到多少钱。
Sample Input
5 1
Sample Output
4.166666
HINT
输出答案时,小数点后第六位后的全部去掉,不要四舍五入.
做了这道题发现我的概率dp真的是太弱了,这么简单的dp式子都推错了。
我们可以用
dp[i][j]
d
p
[
i
]
[
j
]
表示已经选了
i
i
张红牌,张黑牌,离全部选完可以得到的收益,那么
dp[i][j]=max(0,dp[i+1][j]∗n−in+m−i−j+dp[i][j+1]∗m−jn+m−i−j)
d
p
[
i
]
[
j
]
=
m
a
x
(
0
,
d
p
[
i
+
1
]
[
j
]
∗
n
−
i
n
+
m
−
i
−
j
+
d
p
[
i
]
[
j
+
1
]
∗
m
−
j
n
+
m
−
i
−
j
)
然后倒推得到dp[0][0]即答案。
另外需要注意本题空间限制为64MB,所以要把二维数组换成滚动数组。
代码:
#include<bits/stdc++.h>
using namespace std;
int n,m;
double dp[5010];
int main()
{
scanf("%d%d",&n,&m);
for(int i=n;i>=0;i--)
for(int j=m;j>=0;j--)
if(i!=n||j!=m)
dp[j]=max(0.0,(dp[j]+1)*(double)(n-i)/(n+m-i-j)+(dp[j+1]-1)*(double)(m-j)/(n+m-i-j));
printf("%.6lf",dp[0]-5e-7);
return 0;
}