#pragma GCC optimize "O2"
#include <stdio.h>
#include <math.h>
#include <algorithm>
#include <vector>
#include <iostream>
#include <string>
#include <map>
#include <set>
#include <queue>
// for iota, accumulate, partial_sum
// #include <numeric>
#include <iomanip>
// #include <fstream>
// #include <deque>
// #include <cmath>
// #include <unordered_map>
// #include <utility>
// #include <unordered_set>
// #include <ctime>
// #include <stack>
// #include <bitset>
// #include <random>
// #include <cstring>
// #include <cassert>
// #include <complex>
using namespace std;
typedef unsigned long long int lu;
typedef long long int ll;
typedef long double ld;
#define v vector<ll>
#define vu vector<lu>
#define vvu vector<vector<lu>>
#define vld vector<ld>
#define vs vector<string>
#define pll pair<ll, ll>
#define vpll vector<pair<ll, ll>>
#define puu pair<lu, lu>
#define vpuu vector<pair<lu, lu>>
const lu MOD = 1000000007;
const ld PI = 2 * acos(0.0);
#define round(x, y) ((x + y - 1) / y)
#define ce(x, y) ((x + y - 1) / y)
#define amax(x, y) \
    if (y > x)     \
        x = y;
#define amin(x, y) \
    if (y < x)     \
        x = y;
#define lcm(x, y) ((x) * (y) / __gcd(x, y))
#define sq(x) ((x) * (x))
#define cb(x) ((x) * (x) * (x))

#define all(x) x.begin(), x.end()

v ga(ll n)
{
    v a;
    for (ll i = 0; i < n; i++)
    {
        ll p;
        // scanf("%lld", &p);
        cin >> p;
        a.push_back(p);
    }
    return move(a);
}

vu gau(lu n)
{
    vu a;
    for (lu i = 0; i < n; i++)
    {
        lu p;
        // scanf("%lu", &p);
        cin >> p;
        a.push_back(p);
    }
    return move(a);
}
vs gas(lu n)
{
    vs a;
    for (lu i = 0; i < n; i++)
    {
        string p;
        // scanf("%lu", &p);
        cin >> p;
        a.push_back(p);
    }
    return move(a);
}

template <typename T, typename A>
void pa(vector<T, A> const &a)
{
    for (T p : a)
    {
        // printf("%lu ", a[i]);
        cout << p << " ";
    }
    cout << "\n";
}

void yes()
{
    cout << "YES\n";
}

void no()
{
    cout << "NO\n";
}

void yesno(int f)
{
    if (f)
        yes();
    else
        no();
}

void solve()
{
    lu n;
    cin >> n;
    vld probs = {0};
    for (lu i = 0; i < n; i++)
    {
        ld x;
        cin >> x;
        probs.push_back(x);
    }

    vvu pascal(n + 1, vu(n + 1, 0));
    pascal[0][0] = 1;
    pascal[1][0] = 1;
    pascal[1][1] = 1;
    for (lu i = 2; i <= n; i++)
    {
        for (lu j = 1; j <= i; j++)
        {
            pascal[i][j] = pascal[i - 1][j] + pascal[i - 1][j - 1];
        }
    }

    vector<vld> ans(n + 1, vld(n + 1, 0));
    // ans[x][y] indicates getting x heads and y tails in
    // x+y moves. obvio, ans[x][y]=ans[x-1][y]*p_{x+y}+ans[x][y-1]*(1-p_{x+y})

    ans[0][0] = 0;
    ans[1][0] = probs[1];
    ans[0][1] = 1 - probs[1];
    for (lu i = 0; i <= n; i++)
    {
        for (lu j = 0; j <= n; j++)
        {
            if (i + j > n || (i == 0 && j == 0))
            {
                continue;
            }
            else if (i == 0 && j > 1)
            {
                ans[i][j] = ans[i][j - 1] * (1 - probs[i + j]);
            }
            else if (j == 0 && i > 1)
            {
                ans[i][j] = ans[i - 1][j] * probs[i + j];
            }
            else if (i > 0 && j > 0)
            {
                ans[i][j] = ans[i - 1][j] * probs[i + j] + ans[i][j - 1] * (1 - probs[i + j]);
            }
        }
    }
    ld a = 0;
    for (lu i = 1 + n / 2, j = n - i; i <= n; i++, j--)
    {
        // cout << "probs of getting " << i << " heads and " << j << " tails is " << ans[i][j] << endl;
        a += ans[i][j];
    }
    cout << fixed << setprecision(15) << a;
}

int main(void)
{
    ios::sync_with_stdio(0);
    cin.tie(0);
    cout.tie(0);

    solve();
    return 0;
}

Measured memory_bytes: 211584