玩OSU!这个游戏,每次操作只有成功与失败,分别记为
0
0
0或者
1
1
1,然后得分为所有的最长
1
1
1的长度的三次方之和。求得分的期望。
记
f
i
f_{i}
fi表示到第
i
i
i的期望得分。考虑每次增加对得分的贡献,那么
f
i
=
f
i
−
1
+
p
i
(
E
(
(
x
+
1
)
3
)
−
E
(
x
3
)
)
f_{i}=f_{i-1}+p_{i}(E((x+1)^3)-E(x^3))
fi=fi−1+pi(E((x+1)3)−E(x3)),其中
x
x
x是
i
−
1
i-1
i−1状态下的长度。
而
E
(
(
x
+
1
)
3
)
−
E
(
x
3
)
=
3
E
(
x
2
)
+
3
E
(
x
)
+
1
E((x+1)^3)-E(x^3)=3E(x^2)+3E(x)+1
E((x+1)3)−E(x3)=3E(x2)+3E(x)+1。
所以考虑维护两个期望分别是
E
(
x
)
E(x)
E(x)和
E
(
x
2
)
E(x^2)
E(x2)
E
x
(
i
)
=
(
E
x
(
i
−
1
)
+
1
)
∗
p
i
Ex(i)=(Ex(i-1)+1)*p_{i}
Ex(i)=(Ex(i−1)+1)∗pi
E
x
2
(
i
)
=
(
E
x
2
(
i
−
1
)
+
2
E
x
(
i
−
1
)
+
1
)
∗
p
i
Ex^2(i)=(Ex^2(i-1)+2Ex(i-1)+1)*p_{i}
Ex2(i)=(Ex2(i−1)+2Ex(i−1)+1)∗pi
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int inf=0x3f3f3f3f;
const ll INF=LONG_LONG_MAX;
const int N=1e5+7;
double p[N];
double E1[N],E2[N],f[N];
int main() {
int n;
scanf("%d",&n);
for(int i=1;i<=n;i++)
scanf("%lf",&p[i]);
for(int i=1;i<=n;i++) {
E1[i]=(E1[i-1]+1)*p[i];
E2[i]=(E2[i-1]+2*E1[i-1]+1)*p[i];
f[i]=f[i-1]+p[i]*(3*E2[i-1]+3*E1[i-1]+1);
}
printf("%.1lf\n",f[n]);
return 0;
}