原题传送门
令
p
i
p_i
pi表示第
i
i
i个技能的概率
a
n
s
=
∑
p
i
∗
d
i
ans=\sum p_i*d_i
ans=∑pi∗di
令
d
p
i
,
j
dp_{i,j}
dpi,j表示前
i
i
i个技能,成功了
j
j
j个的概率
d
p
i
,
j
=
d
p
i
−
1
,
j
∗
(
1
−
p
i
)
r
−
j
+
d
p
i
−
1
,
j
−
1
∗
[
1
−
(
1
−
p
i
)
r
−
j
+
1
]
dp_{i,j}=dp_{i-1,j}*(1-p_i)^{r-j}+dp_{i-1,j-1}*[1-(1-p_i)^{r-j+1}]
dpi,j=dpi−1,j∗(1−pi)r−j+dpi−1,j−1∗[1−(1−pi)r−j+1]
p
i
=
∑
d
p
i
−
1
,
j
∗
[
1
−
(
1
−
p
i
)
r
−
j
]
p_i=\sum dp_{i-1,j}*[1-(1-p_i)^{r-j}]
pi=∑dpi−1,j∗[1−(1−pi)r−j]
Code:
#include <bits/stdc++.h>
#define maxn 251
using namespace std;
double p[maxn], dp[maxn][maxn], power[maxn][maxn], d[maxn];
int n, m;
int main(){
int T; scanf("%d", &T);
while (T--){
scanf("%d%d", &n, &m);
for (int i = 1; i <= n; ++i){
scanf("%lf%lf", &p[i], &d[i]);
power[i][0] = 1;
for (int j = 1; j <= m; ++j) power[i][j] = power[i][j - 1] * (1 - p[i]);
}
dp[0][0] = 1;
for (int i = 1; i <= n; ++i)
for (int j = 0; j <= i; ++j){
dp[i][j] = dp[i - 1][j] * power[i][m - j];
if (j) dp[i][j] += dp[i - 1][j - 1] * (1 - power[i][m - j + 1]);
}
double ans = 0;
for (int i = 1; i <= n; ++i){
double s = 0;
for (int j = 0; j <= i - 1; ++j) s += dp[i - 1][j] * (1 - power[i][m - j]);
ans += s * d[i];
}
printf("%.10lf\n", ans);
}
return 0;
}