CF--Let's Play Osu!--期望DP

本文探讨了在简化版Osu!游戏中,基于每个点击正确率的概率,如何计算玩家得分的数学期望。通过分析连续正确点击的不同组合,提出了一种高效算法来计算预期得分,适用于大量点击情况。

D. Let's Play Osu!

time limit per test

2 seconds

memory limit per test

256 megabytes

input

standard input

output

standard output

You're playing a game called Osu! Here's a simplified version of it. There are n clicks in a game. For each click there are two outcomes: correct or bad. Let us denote correct as "O", bad as "X", then the whole play can be encoded as a sequence of n characters "O" and "X".

Using the play sequence you can calculate the score for the play as follows: for every maximal consecutive "O"s block, add the square of its length (the number of characters "O") to the score. For example, if your play can be encoded as "OOXOOOXXOO", then there's three maximal consecutive "O"s block "OO", "OOO", "OO", so your score will be 22 + 32 + 22 = 17. If there are no correct clicks in a play then the score for the play equals to 0.

You know that the probability to click the i-th (1 ≤ i ≤ n) click correctly is pi. In other words, the i-th character in the play sequence has piprobability to be "O", 1 - pi to be "X". You task is to calculate the expected score for your play.

Input

The first line contains an integer n (1 ≤ n ≤ 105) — the number of clicks. The second line contains n space-separated real numbers p1, p2, ..., pn (0 ≤ pi ≤ 1).

There will be at most six digits after the decimal point in the given pi.

Output

Print a single real number — the expected score for your play. Your answer will be considered correct if its absolute or relative error does not exceed 10 - 6.

Examples

input

Copy

3
0.5 0.5 0.5

output

Copy

2.750000000000000

input

Copy

4
0.7 0.2 0.1 0.9

output

Copy

2.489200000000000

input

Copy

5
1 1 1 1 1

output

Copy

25.000000000000000

Note

For the first example. There are 8 possible outcomes. Each has a probability of 0.125.

  • "OOO"  →  32 = 9;
  • "OOX"  →  22 = 4;
  • "OXO"  →  12 + 12 = 2;
  • "OXX"  →  12 = 1;
  • "XOO"  →  22 = 4;
  • "XOX"  →  12 = 1;
  • "XXO"  →  12 = 1;
  • "XXX"  →  0.

So the expected score is 

 

题意:连续长度为l的O得分为l^2。给出各个点为O的概率,求得分期望。

 gi=g[i-1]*p+p。

gi是左边连续O的数量期望,根据期望的连续性质,第i点的期望=第i-1点期望*当前点为O概率+前面没有O*当前为O的概率。

然后fi是第i点得分期望。

fi=fi-1*(1-p)即当前不是O的得分期望。

然后fi+=f[i-1]*p当前是O的得分期望。

然后fi-=g[i-1]^2*p减去重复的得分期望。

然后fi+=(g[i-1]+1)^2*p。

#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#define MAXN 100005
using namespace std;
int n;
double p,f[MAXN],g[MAXN];
int main()
{
    while(~scanf("%d",&n))
    {
        for(int i=1;i<=n;i++)
        {
            scanf("%lf",&p);
            g[i]=(g[i-1]+1)*p;
            f[i]=f[i-1]*(1-p);
            f[i]+=(f[i-1]-g[i-1]*g[i-1]+(1+g[i-1])*(1+g[i-1]))*p;
        }
        printf("%.10lf\n",f[n]);
    }
    return 0;
}
#include <bits/stdc++.h>
using namespace std;

const int N = 100010;

int n; double p[N], q[N], ans;

int main () {
    cin >> n;
    for (int i = 1; i <= n; ++i) {
        cin >> p[i];
        q[i] = p[i] * (q[i - 1] + 1);
        ans += p[i] * (q[i] * 2 - 1);
    }
    printf ("%.10lf\n", ans);
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值