Codeforces 498B Name That Tune 概率dp (看题解)
刚开始我用前缀积优化dp, 精度炸炸的。
我们可以用f[ i ][ j ] 来推出f[ i ][ j + 1 ], 记得加加减减仔细一些。。。
#include<bits/stdc++.h> #define LL long long #define fi first #define se second #define mk make_pair #define PLL pair<LL, LL> #define PLI pair<LL, int> #define PII pair<int, int> #define SZ(x) ((int)x.size()) #define ull unsigned long long using namespace std; const int N = 5000 + 7; const int inf = 0x3f3f3f3f; const LL INF = 0x3f3f3f3f3f3f3f3f; const int mod = 1e9 + 7; const double eps = 1e-8; const double PI = acos(-1); int n, T, t[N]; double dp[N][N], p[N], q[N], f[N]; int main() { scanf("%d%d", &n, &T); for(int i = 1; i <= n; i++) { scanf("%lf%d", &p[i], &t[i]); p[i] /= 100; q[i] = 1 - p[i]; f[i] = pow(q[i], t[i]); } double ans = 0; dp[0][0] = 1; for(int i = 1; i <= n; i++) { double gg = 0; for(int j = 1; j <= T; j++) { if(j < t[i]) gg = gg * q[i] + p[i] * dp[i - 1][j - 1]; else if(j == t[i]) gg = gg * q[i] + p[i] * dp[i - 1][j - 1] + f[i] * dp[i - 1][j - t[i]]; else gg = gg * q[i] + p[i] * dp[i - 1][j - 1] - f[i] * dp[i - 1][j - t[i] - 1] + f[i] * dp[i - 1][j - t[i]]; dp[i][j] = gg; ans += dp[i][j]; } } printf("%.12f\n", ans); return 0; } /* */