bzoj 4318 OSU! 题解(期望)

本文介绍了如何利用期望的线性性解决bzoj 4318题目,通过递推公式推导求解最长连续1的长度三次方期望值。文章详细阐述了从一次方、二次方期望到三次方期望的推导过程,并提供了代码实现。
摘要由CSDN通过智能技术生成

原题链接:
洛谷
B站OJ

题意简述

给定 n n n,有一个长度为 n n n 01 01 01串,其中第 i i i个位置 = 1 =1 =1的概率为 p i p_i pi。定义一个 01 01 01序列的得分为 l 3 l^3 l3,其中 l l l是最长连续 1 1 1的长度。求得分的期望值。

数据

输入

第一行一个正整数 n ( n &lt; = 1 e 5 ) n(n&lt;=1e5) n(n<=1e5)。接下来 n n n行每行一个小数,表示每个位置是 1 1 1的概率。

输出

输出一行一个整数,表示得分的期望值。

样例

输入
3
0.5
0.5
0.5
输出
6.0

思路

众所周知期望的线性性: E ( x + y ) = E ( x ) + E ( y ) E(x+y)=E(x)+E(y) E(x+y)=E(x)+E(y)
同理也容易推得: E ( x + y + z ) = E ( x ) + E ( y ) + E ( z ) E(x+y+z)=E(x)+E(y)+E(z) E(x+y+z)=E(x)+E(y)+E(z)
E ( a 1 + a 2 . . . + a k ) = E ( a 1 ) + E ( a 2 ) . . . + E ( a k ) E(a_1+a_2...+a_k)=E(a_1)+E(a_2)...+E(a_k) E(a1+a2...+ak)=E(a1)+E(a2)...+E(ak)
这个珂以用来干嘛呢?比如我们要求 x x x的期望,我们知道 x x x有几种情况,然后我们知道每种情况的期望,那么我们只要把这些期望加起来,就是 x x x的期望了。

这种题,直接枚举每个位置的 01 01 01情况肯定是不珂取的,所以。。。递推?

尝试一下吧。我们设 f ( i ) f(i) f(i)为:考虑前 i i i个位置的答案。那么我们要用 f ( i − 1 ) f(i-1) f(i1)求出 f ( i ) f(i) f(i)
为了方便思考(即配合期望的概念),我们设前 i − 1 i-1 i1个位置有 k k k种取值,其中每种取值的概率是 q 1 , q 2 . . . q k q_1,q_2...q_k q1,q2...qk,最长连续 1 1 1的长度是 v 1 , v 2 . . . v k v_1,v_2...v_k v1,v2...vk,那么前 i − 1 i-1 i1个位置的答案(即三次方的期望)就是
f ( i − 1 ) = ∑ j = 1 k q j ∗ v j 3 f(i-1)=\sum\limits_{j=1}^{k}q_j*v_j^3 f(i1)=j=1kqjvj3

我们现在有 p i p_i pi的概率会使第 i i i个位置是 1 1 1。此时的每个 v i v_i vi都要 + 1 +1 +1变成: p i ∑ j = 1 k q j ( v j + 1 ) 3 p_i\sum\limits_{j=1}^{k}q_j(v_j+1)^3 pij=1kqj(vj+1)3,用 f ( i − 1 ) f(i-1) f(i1)表示,也就是
p i ∑ j = 1 k q j ( v j 3 + 3 v j 2 + 3 v j + 1 ) p_i\sum\limits_{j=1}^{k}q_j(v_j^3+3v_j^2+3v_j+1) pij=1kqj(vj3+3vj2+3vj+1)
= p i ( f ( i − 1 ) + ∑ j = 1 k q j 3 v j 2 + ∑ j = 1 k q j 3 v j + ∑ j = 1 k q j ) =p_i(f(i-1)+\sum\limits_{j=1}^{k}q_j3v_j^2+\sum\limits_{j=1}^{k}q_j3v_j+\sum\limits_{j=1}^{k}q_j) =pi(f(i1)+j=1kqj3vj2+j=1kqj3vj+j=1kqj)
我们知道,一个变量所有取值的概率和肯定是 1 1 1,即 ∑ j = 1 k q j = 1 \sum\limits_{j=1}^{k}q_j=1 j=1kqj=1
原式
= p i ( f ( i − 1 ) + ∑ j = 1 k q j 3 v j 2 + ∑ j = 1 k q j 3 v j + 1 ) =\red{p_i(f(i-1)+\sum\limits_{j=1}^{k}q_j3v_j^2+\sum\limits_{j=1}^{k}q_j3v_j+1)} =pi(f(i1)+j=1kqj3vj2+j=1kqj3vj+1)
另外还有 1 − p i 1-p_i 1pi的概率会使第 i i i个位置是 0 0 0。此时 v i v_i vi不变。此时的答案:
( 1 − p i ) ∑ j = 1 k q j v j 3 (1-p_i)\sum\limits_{j=1}^{k}q_jv_j^3 (1pi)j=1kqjvj3
= ( 1 − p i ) f ( i − 1 ) =\red{(1-p_i)f(i-1)} =(1pi)f(i1)

那么,根据线性性,我们把这些情况加起来,就是我们要求的期望值 f ( i ) f(i) f(i),即
p i ( f ( i − 1 ) + ∑ j = 1 k q j 3 v j 2 + ∑ j = 1 k q j 3 v j + 1 ) + ( 1 − p i ) f ( i − 1 ) p_i(f(i-1)+\sum\limits_{j=1}^{k}q_j3v_j^2+\sum\limits_{j=1}^{k}q_j3v_j+1)\red{+}(1-p_i)f(i-1) pi(f(i1)+j=1kqj3vj2+j=1kqj3vj+1)+(1pi)f(i1)
(其中红色的 + + +是为了区分两个情况)

我们会发现,右边很好求,但是左边有两个很烦人的东西:
平方的期望(即 ∑ j = 1 k q i v i 2 \sum\limits_{j=1}^{k}q_iv_i^2 j=1kqivi2) 和 一次方的期望(即 ∑ j = 1 k q i v i \sum\limits_{j=1}^{k}q_iv_i j=1kqivi
但这两个东西也不是不能求,和三次方类似的推一下转移即珂。我们上面已经推出来三次方的转移了,这两个还不好推?

如果您真的感觉不好推,那么我深感抱歉,并在这里给出推导过程。
我们设前 i i i个位置上一次方的期望为 l 1 ( i ) l_1(i) l1(i),二次方的期望为 l 2 ( i ) l_2(i) l2(i)
显然,
l 1 ( i ) = p i ∑ j = 1 k q j ( v j + 1 ) = p i ( f ( i − 1 ) + 1 ) l_1(i)=p_i\sum\limits_{j=1}^{k}q_j(v_j+1)=p_i(f(i-1)+1) l1(i)=pij=1kqj(vj+1)=pi(f(i1)+1)
l 2 ( i ) = p i ∑ j = 1 k q j ( v j + 1 ) 2 = p i ∑ j = 1 k q j ( v j 2 + 2 v j + 1 ) l_2(i)=p_i\sum\limits_{j=1}^{k}q_j(v_j+1)^2=p_i\sum\limits_{j=1}^{k}q_j(v_j^2+2v_j+1) l2(i)=pij=1kqj(vj+1)2=pij=1kqj(vj2+2vj+1)
= p i ( l 2 ( i − 1 ) + 2 l 1 ( i − 1 ) + 1 ) =p_i(l_2(i-1)+2l_1(i-1)+1) =pi(l2(i1)+2l1(i1)+1)
然后就珂以求得
f ( i ) = p i ( f ( i − 1 ) + 3 l 2 ( i − 1 ) + 3 l 1 ( i − 1 ) + 1 ) + ( 1 − p i ) f ( i − 1 ) f(i)=p_i(f(i-1)+3l_2(i-1)+3l_1(i-1)+1)+(1-p_i)f(i-1) f(i)=pi(f(i1)+3l2(i1)+3l1(i1)+1)+(1pi)f(i1)

代码(式子长,代码短):

#include<bits/stdc++.h>
using namespace std;
namespace Flandle_Scarlet
{
    #define real double
    #define N 100100
    int n;
    real p[N];
    real l1[N],l2[N],f[N];
    void Input()
    {
        scanf("%d",&n);
        for(int i=1;i<=n;++i)
        {
            scanf("%lf",&p[i]);
        }
    }
 
    void Soviet()
    {
        for(int i=1;i<=n;++i)
        {
            l1[i]=p[i]*(l1[i-1]+1);
            l2[i]=p[i]*(l2[i-1]+2*l1[i-1]+1);
            f[i]=p[i]*(f[i-1]+3*l2[i-1]+3*l1[i-1]+1)+(1-p[i])*f[i-1];
            //上面的式子
        }
        printf("%.1f\n",f[n]);
    }
    void IsMyWife()
    {
        if (0)
        {
            freopen("","r",stdin);
            freopen("","w",stdout);
        }
        Input();
        Soviet();
    }
};
int main()
{
    Flandle_Scarlet::IsMyWife();
    return 0;
}

回到总题解界面

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值