[HbFS-]Red is good

http://www.gdfzoj.com/oj/problem/470
桌面上有R张红牌和B张黑牌,随机打乱顺序后放在桌面上,开始一张一张地翻牌,翻到红牌得到1美元,黑牌则付出1美元。可以随时停止翻牌,在最优策略下平均能得到多少钱。 输出答案时,小数点后第六位后的全部去掉,不要四舍五入.
令 f[i][j] 为 剩 i个红 j个黑时的期望
算期望 可以看出
f[i,j]:=f[i,j]+(i/(i+j)*(f[i-1,j]+1));
f[i,j]:=f[i,j]+(j/(i+j)*(f[i,j-1]-1));
i/(i+j) j/(i+j) 为概率
f[i-1,j]+1 f[i,j-1]-1为 所得效应
最后与 0 取 max 如小于 0 停止翻牌
最后 处理
f[r][b] -= 0.5;(向下取整)
f[r][b] = fabs(f[r][b]);(防止输出 -0.000000)
printf(“%.6lf\n”,f[r][b]);

下面是代码

#include
#include
#include
using namespace std;
double f[5050][5050];
int r,b,i,j,k,l,m,n;
int main(){
    scanf("%d%d",&r,&b);
    for(i=0;i<=r;i++)
       for(j=0;j<=b;j++){
           if (i) f[i][j] += (double)i/(double)(i+j)*(f[i-1][j]+1);
           if (j) f[i][j] += (double)j/(double)(i+j)*(f[i][j-1]-1);
           f[i][j]=max(0.0,f[i][j]);
       }
       f[r][b] -= 0.5;
       f[r][b] = fabs(f[r][b]);
       printf("%.6lf\n",f[r][b]);
       return 0;
}
var i,j,k,l,m,n,q,w,r,b:longint;
    f:array[0..5000,0..5000] of double;
    t:double;
function max(p,o:double):double;
begin
    if p>o then exit(p);exit(o);
end;
begin
    readln(r,b);
    for i:=0 to r do
      for j:=0 to b do begin
         if i>0 then f[i,j]:=f[i,j]+(i/(i+j)*(f[i-1,j]+1));
         if j>0 then f[i,j]:=f[i,j]+(j/(i+j)*(f[i,j-1]-1));
         f[i,j]:=max(f[i,j],0);
    end;
     t:=f[r,b];t:=t-0.5;t:=abs(t);
     writeln(t:0:6);
end.

你可能感兴趣的:(dp,dp)