BZOJ 1419 Red is good
2017.12.26
2017.12.26
给你一些牌,这些牌只有两种:红牌和黑牌,抽到红牌得一元,抽到黑牌扣一元,问使用最优策略最终期望得到的钱数。
初探概率期望……首先考虑正着推。设$F_{i,j}$是红牌剩余i张,黑牌剩余j张的期望收入,我们得到方程
$$F_{i,j} = \frac{i+1}{i+1+j}(F_{i+1,j}+1)+\frac{j+1}{i+j+1}(F_{i,j+1}-1)$$
但是这出现了一个问题:我们既然选择这样推那么就需要知道最大的,也就是初始F值。但是这就是我们要求的东西= =
怕是石乐志刚刚才想明白咋正确地反着推……设$F_{i,j}$是红牌剩余i张,黑牌剩余j张的期望收入,那么对于$F_{i+1,j}$也就是最先抽的这张是红色的情况就一定有这个东西是$F_{i,j}$加上收入而来的。原因是前者是上一个最终状态,推到新的最终状态的时候直接加上去就可以了,而不能和正着推放在一起讨论。
$$F_{i,j} = \frac{i}{i+j}(F_{i-1,j}+1)+\frac{j}{i+j}(F_{i,j-1}-1)$$
#include <cmath>
#include <cstdio>
#include <algorithm>
using namespace std;
int r,b,flg;
double f[2][5010];
int main()
{
scanf("%d%d",&r,&b);
for(int i=1;i<=r;++i)
{
flg=i%2;
f[flg][0]=i;
for(int j=1;j<=b;++j)
{
f[flg][j]=(1.0*(i)/(i+j))*(f[flg^1][j]+1)+(1.0*(j)/(i+j))*(f[flg][j-1]-1);
if(f[flg][j]<0) f[flg][j]=0;
}
}
printf("%.6lf",floor(f[r%2][b]*1000000)/1000000);
return 0;
}