P3239 [HNOI2015]亚瑟王

第二道概率 \(DP\)

显然每一张牌在一次中是只能选一次的。

期望: $$\sum\limits^{N}_{i=1} g_i \times d_i$$,其中 \(g_i\) 为第 \(i\) 张牌在 \(r\) 轮中使用的总概率。

其中设 \(f_{i,j}\) 为在第 \(i\) 轮中(一共跑了 \(i\) 张牌)选了 \(j\) 张牌的概率。那么 $$g_i+=\sum\limits^{\ min{i-1,r-1}}{j=0}f \times (1-(1-p_i)^{r-j})$$

其中 \(f_{i,j}\) 要分情况转移:

  • 选: $$f_{i,j}+=f_{i-1,j-1} \times (1-(1-p_i)^{r-j+1}))$$

  • 不选: $$f_{i,j}+=f_{i-1,j} \times (1-p_i)^{r-j}$$

我们先预处理 \(times_{i,j}\) 代表第 \((1-p_i)^j\) 的值。最后统计答案即可。(注意,如果按照我的做法要判 \(r=0\) 的情况)

// luogu-judger-enable-o2
Uses math;

var
    times:array[-1..300,-1..300] of extended;
    fuck:array[-1..300,-1..300] of extended;
    proba,g:array[-1..5100] of extended;
    attack:array[-1..5100] of longint;
    i,j,n,r,text:longint;
    ans:extended;

procedure Work;
begin
    fillchar(times,sizeof(times),0);
    fillchar(fuck,sizeof(fuck),0);
    fillchar(g,sizeof(g),0);
    read(n,r); ans:=0;
    if (n=0)or(r=0) then begin writeln(ans:0:10); exit; end;
    for i:=1 to n do read(proba[i],attack[i]);
    for i:=1 to n do times[i,1]:=1-proba[i];
    for i:=1 to n do for j:=2 to r do times[i,j]:=times[i,j-1]*(1-proba[i]);
    fuck[1,0]:=times[1,r]; fuck[1,1]:=1-times[1,r]; g[1]:=fuck[1,1];
    for i:=2 to n do for j:=0 to min(i,r) do
    begin
        fuck[i,j]:=fuck[i,j]+fuck[i-1,j-1]*(1-times[i,r-j+1]);
        fuck[i,j]:=fuck[i,j]+fuck[i-1,j]*times[i,r-j];
    end;
    for i:=2 to n do for j:=0 to min(i-1,r-1) do g[i]:=g[i]+fuck[i-1,j]*(1-times[i,r-j]);
    for i:=1 to n do ans:=ans+g[i]*attack[i]; writeln(ans:0:10);
end;

begin
    read(text);
    repeat
        dec(text); Work;
    until text=0;
end.
posted @ 2019-01-25 21:56  _ARFA  阅读(107)  评论(0编辑  收藏  举报