第二道概率 \(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_{i-1,j} \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.