P1654 OSU!

传送门

这题又一次让我感受到我概率/期望DP的薄弱


思路

(紧抓期望的定义式)

\(f_i\) 表示考虑到第 \(i\) 位时的得分,\(p_l\) 表示到第 \(i\) 位连续 \(l\) 位为 \(1\) 的概率,\(P\) 表示 第 \(i + 1\)\(1\) 的概率

如果 \(i + 1\) 不为 \(1\) ,那么就没有贡献,则当前期望仍为 \(f_i\)

反之,考虑连续 \(l\) 位的 \(1\) 产生的期望:\(P\sum_{l=0}^i p_l(3l ^2+3l+1)\)

所以合起来就是

\[f_{i+1}=f_i+P\sum_{l=0}^i p_l(3l ^2+3l+1) \]

我们注意到,\(\sum_{l=0}^ip_l l\) 其实是当分数为一次时的期望;\(\sum_{l=0}^ip_l l^2\) 是分数为二次时的期望(都是要求只有一段 \(1\),且终点是第 \(i\) 位)

那么我们有递推式:

\[E(l_{i + 1})=P(E(l_i)+\sum_{l=0}^i p_l)=P(E(l_i) + 1) \]

\[E(l^2_{i + 1})=P(E(l^2_i)+\sum_{l=0}^i p_l(2l+1))=P(E(l^2_i) + 2E(l_i) + 1) \]

一直递推即可


代码

#include<iostream>
#include<fstream>
#include<algorithm>
#include<cmath>
#include<cstdlib>
#include<cstring>
#include<queue>
#include<map>
#include<set>
#include<bitset>
#define LL long long
#define FOR(i, x, y) for(int i = (x); i <= (y); i++)
#define ROF(i, x, y) for(int i = (x); i >= (y); i--)
int n; double p, e1, e2, ans;
signed main()
{
#ifndef ONLINE_JUDGE
    freopen("test.in", "r", stdin);
    freopen("test.out", "w", stdout);
#endif
    scanf("%d", &n);
    FOR(i, 1, n)
    {
        scanf("%lf", &p);
        ans += p * (3.0 * e2 + 3.0 * e1 + 1.0);
        e2 = p * (e2 + 2.0 * e1 + 1.0);
        e1 = p * (e1 + 1.0);
    }
    printf("%.1lf", ans);
    return 0;
}
posted @ 2022-08-13 16:25  zuytong  阅读(24)  评论(0编辑  收藏  举报