P1654 做题记录
观前提示:作者期望水平不高,如果公式等有错欢迎指出
我们知道,(粗略地来说)期望是一系列事件的结果乘上发生的概率。
考虑到 \(n-1\) 位时连续长度的期望:\(EX=\sum x_ip_i\),如何用它求出下一位的期望?若 \(n\) 发生,则 \(x\) 的长度增加;否则原地消失。\(EX=\sum x_{i+1}p_ip_n+0\). 因此,\(E_n=(E_{n-1}+1)p_n\)。
不难发现,\(\sum x_ip_i\) 中 \(x_i\) 可以为 \(0\),这不影响期望的大小,且转移时的 \(+1\) 包含了从 \(0\) 到 \(1\) 的情况。
接下来是二次期望;由于 \(E(X^2) \not = E(X)^2\),因此我们不能偷懒。但有了一次的经验,我们只要考虑它如何转移。\(E(X^2)=\sum x_i^2p_i\),转移到下一个 \(n\) 时:
\[\begin{align*}
E(X^2) & =\sum (x_i+1)^2p_ip_n \\
& = p_n (\sum x_i^2p_i + \sum 2x_ip_i + \sum 1p_i) \\
& = p_n (E_{n-1}(X^2) + 2EX + 1)
\end{align*}\]
关于最后一步:我们知道 \(p_i\) 是相等的,算上 \(x_0p_0\) 这一项后 \(\sum p_i=1\)(\(x_i\) 的长度在 \([0,p_n]\) 间的概率是 \(1\))。
同样地,\(E(X^3)\) 也能推出来。
code:
#include <cstdio>
#define sd std::
#define UP(i,s,e) for(auto i=s; i<e; ++i)
namespace m{ // }{{{
int in;
double lastx1, lastx2, lastx3, x1, x2, x3;
double ans;
void work(){
scanf("%d", &in);
UP(i, 0, in){
double p;
scanf("%lf", &p);
x1 = (lastx1+1)*p;
x2 = (lastx2+2*lastx1+1)*p;
x3 = (lastx3+3*lastx2+3*lastx1+1)*p;
ans += lastx3*(1-p);
lastx1 = x1;
lastx2 = x2;
lastx3 = x3;
}
printf("%.1lf", ans+x3);
}
} // {}}}
int main(){m::work(); return 0;}