Qunju save me... (Expect DP)

Qunju save me... (Expect DP)

Topic link: https://ac.nowcoder.com/acm/contest/17583/E
Topic source: Niuke.com

Problem Description

As we all know, Niu Kele has a very strong tongue ability.
Niu Kele wants to talk about n things, and we will number these things from 1∼n.
It takes one unit of time for Niu Kele to talk about one thing, but Niu Kele speaks things differently from ordinary people: when Niu Kele finishes talking about the i-th thing, only pi {p_i}piProbability to continue to talk about the next thing (i+1th thing), that is to say, Niu Kele has (1- pi p_ipi) probability starts from the i-1th event!
When Niu Kele finishes talking about the nth thing and decides to talk about the next thing, Niu Kele has finished talking about the nth thing.
Niu Mei is an impatient girl. She wants to ask you how long Niu Kele expects to talk about n things.

Input

The first line is an integer n
The second line is n floating point numbers, representing pi p_ipi, guarantee that p 1 p_1p1=1


Output

One floating point number per line, indicating how long Niu Kele expects to finish all the things (reserved to 3 decimal places)


Sample Input

4
1 0.6 0.4 0.2

Sample Output

38.333

Remark

For 20% of the data, 1 ≤ \le n≤ \le 20
for 100% of the data, 1≤ \le n≤ \le 1 0 5 10^5 105


Solution

This question needs to calculate the mathematical expectation, because there are actually countless situations to finish all n things, so the ordinary method of calculating the mathematical expectation is not feasible. At this time, the idea of ​​​​dynamic programming is needed:


f i f_i fiIndicates the time required to speak from the first event to the i-th event. Then the obvious answer is fn f_{n}fn

nah fi f_ifiWhich states will be transferred?

  1. f i f_i fiThere are pi p_ipiThe probability of : directly from fi − 1 f_{i-1}fi1transfer over
  2. f i f_ifiThere is 1 − pi 1-p_i1piThe probability of: by fi − 1 f_{i-1}fi1First transfer to fi − 2 f_{i-2}fi2, and then by fi − 2 f_{i-2}fi2back to fi f_{i}fi

The state transition equation should be:
fi = pi − 1 ∗ ( fi − 1 + 1 ) + ( 1 − pi − 1 ) ∗ ( fi − 1 + 1 + fi − fi − 2 ) f_i=p_{i-1 }*(f_{i-1}+1)+(1-p_{i-1})*(f_{i-1}+1+f_i-f_{i-2})fi=pi1(fi1+1)+(1pi1)(fi1+1+fifi2)
where, fi − fi − 2 represents the time required to speak from i − 2 to i where f_i-f_{i-2} represents the time required to speak from i-2 to iAmong them ,fifi2means from i2 The time
shift required for i is simplified:fi = ( fi − 1 + 1 + ( pi − 1 − 1 ) ∗ fi − 2 ) / pi − 1 f_i=(f_{i-1} +
1+(p_{i-1}-1)*f_{i-2})/p_{i-1}fi=(fi1+1+(pi11)fi2)/pi1


Code

#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>

using namespace std;
typedef long long ll;

const int N=1e5+100;

int n;
double f[N],p[N];

void solve()
{
    
    
    scanf("%d",&n);
    for(int i=0;i<n;i++)
    scanf("%lf",p+i);

    // 公式推导
    // f[i]=p[i-1]*(f[i-1]+1)+(1-p[i-1])*(f[i-1]+1+f[i]-f[i-2])
    // ->  f[i]=(f[i-1]+1+(p[i-1]-1)*f[i-2])/p[i-1]

    f[1]=1;
    for(int i=2;i<=n;i++)
    {
    
    
        f[i]=(f[i-1]+1+(p[i-1]-1)*f[i-2])/p[i-1];
    }
    printf("%.3lf\n",f[n]);
}


int main()
{
    
    
#ifdef LOCAL
    freopen("in.txt","r",stdin);
    //freopen("out.txt","w",stdout);
#endif
    solve();

    /*
    *
    *  ┏┓   ┏┓+ +
    * ┏┛┻━━━┛┻┓ + +
    * ┃       ┃
    * ┃   ━   ┃ ++ + + +
    *  ████━████+
    *  ◥██◤ ◥██◤ +
    * ┃   ┻   ┃
    * ┃       ┃ + +
    * ┗━┓   ┏━┛
    *   ┃   ┃ + + + +Code is far away from  
    *   ┃   ┃ + bug with the animal protecting
    *   ┃    ┗━━━┓ 神兽保佑,代码无bug 
    *   ┃        ┣┓
    *    ┃        ┏┛
    *     ┗┓┓┏━┳┓┏┛ + + + +
    *    ┃┫┫ ┃┫┫
    *    ┗┻┛ ┗┻┛+ + + +
    */
}



Finally, thank you for your study~

Guess you like

Origin blog.csdn.net/weixin_43800577/article/details/118004288