Codeforces Round #265 (Div. 1) D. World of Darkraft - 2
由期望的线性性,$E(\sum \limits_{i=1}^{k} X_i) = \sum \limits_{i=1}^k E(X_i)=kE(X_1)$,只需要求出打完 $n$ 个怪后一件武器的期望值。
$dp[i][j]$ 表示打完 $i$ 个怪后,初始 level 为 $j$ 的武器能赚的钱,$dp[0][j] = 0$,所求为 $dp[n][1]$。
转移方程为 $dp[i][j] = \frac{k-1}{k}dp[i-1][j] + \frac{1}{k}(\frac{1}{j+1}\sum \limits_{t=1}^{j}(dp[i-1][j]+t)+\frac{1}{j+1}(dp[i-1][j+1]+j))=\frac{k-1}{k}dp[i-1][j]+\frac{1}{k(j+1)}(jdp[i-1][j]+dp[i-1][j+1]+\frac{j(j+3)}{2})$
然后因为是浮点计算,第二维只要到 $O(\sqrt n)$ 级别就可以了。
#include <bits/stdc++.h> #define db double db dp[2][850]; int main() { int n, k; scanf("%d%d", &n, &k); int t = std::min(n, 800); int now = 1; for (int i = 1; i <= n; i++) { for (int j = t; j >= 1; j--) { dp[now][j] = dp[now ^ 1][j] * (k - 1) / (1.0 * k) + (j * dp[now ^ 1][j] + dp[now ^ 1][j + 1] + j * (j + 3) / 2.0) / (1.0 * k * (j + 1)); } now ^= 1; } printf("%.10f\n", k * dp[now ^ 1][1]); return 0; }