桌面上有R张红牌和B张黑牌,随机打乱顺序后放在桌面上,开始一张一张地翻牌,翻到红牌得到1美元,黑牌则付出1美元。可以随时停止翻牌,在最优策略下平均能得到多少钱。
概率DP是真的难。。
首先想到期望DP:
f[Red][Blue]=RedRead+Blue∗(f[Red−1][Blue]+1)+BlueRed+Blue∗(f[Red][Blue−1]−1)
。
可惜这个是错的。原因在于如果当前状态继续下去使价值变劣那么不会选(最优策略),只需要取 f[i][j]=max{f[i][j],0} 就好了,注意卡空间需要滚动数组。。
(最神奇的是 f[i][i] 居然不是0,还有 f[i][i+k] 还有可能是正数。。期望DP太神了。)
#include<bits/stdc++.h>
using namespace std;
double f[2][5005];
int R,B,now=0;
int main(){
scanf("%d%d",&R,&B);
for(int i=1;i<=R;i++)f[now][i]=i;
for(int i=1;i<=B;i++){
now^=1;
for(int j=1;j<=R;j++){
f[now][j]=max(0.0,(double)j/(i+j)*(f[now][j-1]+1.0)+(double)i/(i+j)*(f[now^1][j]-1.0));
}
}
int t=f[now][R];
cout<<t<<".";f[now][R]-=t;
for(int i=1;i<=6;i++){
f[now][R]*=10.0;
t=f[now][R];
f[now][R]-=t;
putchar('0'+t);
}
}