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;
}