考虑对每张牌求出出掉它的概率那么期望就可以轻易算出
一张牌被考虑的次数与考虑到它的轮数有关,而考虑到一个点的轮数与前面选了几张牌有关
于是令
f
[
i
]
[
j
]
f[i][j]
f[i][j] 表示
r
r
r 轮中,第
i
i
i 个之前及
i
i
i 选了
j
j
j 个的概率
那么一张牌最后出出去的概率就是
p
i
=
∑
j
=
0
i
−
1
f
[
i
−
1
]
[
j
]
∗
(
1
−
(
1
−
p
)
r
−
j
)
p_i=\sum_{j=0}^{i-1}f[i-1][j]*(1-(1-p)^{r-j})
pi=j=0∑i−1f[i−1][j]∗(1−(1−p)r−j)
f
f
f 的转移枚举当前选不选就可以了
f
[
i
]
[
j
]
=
f
[
i
−
1
]
[
j
]
∗
(
1
−
p
)
r
−
j
+
f
[
i
−
1
]
[
j
−
1
]
∗
(
1
−
(
1
−
p
)
r
−
(
j
−
1
)
)
f[i][j]=f[i-1][j]*(1-p)^{r-j}+f[i-1][j-1]*(1-(1-p)^{r-(j-1)})
f[i][j]=f[i−1][j]∗(1−p)r−j+f[i−1][j−1]∗(1−(1−p)r−(j−1))
#include<bits/stdc++.h>
#define cs const
using namespace std;
cs int N = 225;
int T, n, r;
double p[N]; int d[N];
double pw[N][N], f[N][N];
int main(){
scanf("%d", &T);
while(T--){
scanf("%d%d", &n, &r);
for(int i = 1; i <= n; i++){
scanf("%lf%d", &p[i], &d[i]);
pw[i][0] = 1;
for(int j = 1; j <= r; j++) pw[i][j] = pw[i][j - 1] * (1 - p[i]);
}
f[0][0] = 1;
for(int i = 1; i <= n; i++){
for(int j = 0; j <= r; j++){
f[i][j] = f[i - 1][j] * pw[i][r - j] + f[i - 1][j - 1] * (1 - pw[i][r - j + 1]);
}
} double ans = 0;
for(int i = 1; i <= n; i++){
double p = 0;
for(int j = 0; j < r; j++) p += f[i - 1][j] * (1 - pw[i][r - j]);
ans += p * d[i];
} printf("%.10lf\n", ans);
} return 0;
}