【题解】LuoGu3239:亚瑟王

    科技2022-08-07  135

    原题传送门 令 p i p_i pi表示第 i i i个技能的概率 a n s = ∑ p i ∗ d i ans=\sum p_i*d_i ans=pidi

    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=dpi1,j(1pi)rj+dpi1,j1[1(1pi)rj+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=dpi1,j[1(1pi)rj]

    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; }
    Processed: 0.010, SQL: 8