题意
-
我们面前有一个长度为 N N N的01序列,位置 a i a_i ai 有 p i p_i pi 的概率是1,否则为0。
-
序列中,一段长为 x x x 的连续1会带来 x 3 x^3 x3 的加分(这段全为1的子区间不能被更长的全1区间包含)
-
求得分期望
思路
-
考虑DP的方法, F i F_i Fi 表示前i位的期望加分。然后对于第 i + 1 i + 1 i+1 位
-
如果为0,则对于总体加分有0贡献
-
我们定义以i为结尾,全1区间长度的期望是
E ( L i ) E(L_i) E(Li)
-
然后,如果第i + 1位为1,则贡献为
E ( ( L i + 1 ) 3 ) − E ( L i 3 ) = 3 ∗ E ( L i 2 ) + 3 ∗ E ( L i ) + 1 E((L_i + 1)^3) - E(L_i^3) = 3 * E(L_i^2) + 3 * E(L_i) + 1 E((Li+1)3)−E(Li3)=3∗E(Li2)+3∗E(Li)+1
-
这是因为i + 1位为1时,所有以i为结尾的全1区间都会延长至i + 1,从而我们必须要放弃之前的这部分贡献,然后加上新的部分,最终得到的是一个二次多项式
-
然后考虑如何计算 E ( L i 2 ) E(L_i^2) E(Li2) 和 E ( L i ) E(L_i) E(Li)
-
对于 E ( L i ) E(L_i) E(Li), 当i + 1位为0时,显然 E ( L i + 1 ) E(L_{i + 1}) E(Li+1) 为0(毕竟不可能成为全一区间结尾了),i + 1位为1时,显然有
E ( L i + 1 ) = E ( L i ) + 1 E(L_{i + 1}) = E(L_i) + 1 E(Li+1)=E(Li)+1 -
对于 E ( L i 2 ) E(L_i^2) E(Li2), 当i + 1位为0时,显然 E ( L i + 1 ) E(L_{i + 1}) E(Li+1) 为0(原因同上),i + 1位为1时,有
E ( L i + 1 2 ) = E ( ( L i + 1 ) 2 ) = E ( L i 2 ) + 2 ∗ E ( L i ) + 1 E(L_{i + 1}^2) = E((L_i + 1)^2) = E(L_i^2) + 2 * E(L_i) + 1 E(Li+12)=E((Li+1)2)=E(Li2)+2∗E(Li)+1 -
总起来也就是说
E ( L i + 1 ) = p i + 1 ∗ ( E ( L i ) + 1 ) E ( L i + 1 2 ) = p i + 1 ∗ E ( ( L i + 1 ) 2 ) = p i + 1 ∗ ( E ( L i 2 ) + 2 ∗ E ( L i ) + 1 ) E(L_{i + 1}) = p_{i + 1} * (E(L_i) + 1) \\ E(L_{i + 1}^2) = p_{i + 1} * E((L_i + 1)^2) = p_{i + 1} * (E(L_i^2) + 2 * E(L_i) + 1) E(Li+1)=pi+1∗(E(Li)+1)E(Li+12)=pi+1∗E((Li+1)2)=pi+1∗(E(Li2)+2∗E(Li)+1)
-
-
- 由i + 1位为1时对加分贡献的式子,可得
F i + 1 = F i + p i + 1 ∗ ( 3 ∗ E ( L i 2 ) + 3 ∗ E ( L i ) + 1 ) F_{i + 1} = F_i + p_{i + 1} * (3 * E(L_i^2) + 3 * E(L_i) + 1) Fi+1=Fi+pi+1∗(3∗E(Li2)+3∗E(Li)+1)
一边计算 F i F_i Fi 一边计算 E ( L i ) E(L_i) E(Li) 和 E ( L i 2 ) E(L_i^2) E(Li2) 即可
AC代码
#include <cstdio>
#include <cstring>
#include <iostream>
#include <algorithm>
using namespace std;
int n;
double p;
int main()
{
scanf("%d", &n);
double acc = 0;
double x2 = 0, x = 0;
for (int i = 0; i < n; ++i)
{
scanf("%lf", &p);
acc += p * (3 * x2 + 3 * x + 1);
x2 = p * (x2 + 2 * x + 1);
x = p * (x + 1);
}
printf("%.1f", acc);
return 0;
}