CodeEff/ECCO huggingface dataset:
# Original solution
N,A,B=list(map(int,input().split()));M=998244353;P=N+1;f=1;F=[1]*P;I=[1]*P;z=0;R=range
for n in R(1,P):F[n]=f=f*n%M
I[N]=i=pow(f,M-2,M)
for n in R(N,1,-1):I[n-1]=i=i*n%M
for k in R(min(A+1,N-B)if N-B-A else A+1):Q=N-B-k-1;z=(z+(B-k)*F[B+k-1]*I[B]*I[k]*F[Q+A-k]*I[Q]*I[A-k])%M
print((z if B else 1))

# Optimized solution
N,A,B=list(map(int,input().split()));M=998244353;P=N+1;f=1;F=[1]*P;I=[1]*P;z=0;R=range
for n in R(1,P):F[n]=f=f*n%M
I[N]=i=pow(f,M-2,M)
for n in R(N,1,-1):I[n-1]=i=i*n%M
for k in R(min(A+1,N-B)if N-B-A else A+1):Q=N-B-k-1;z+=(B-k)*F[B+k-1]*I[B]*I[k]*F[Q+A-k]*I[Q]*I[A-k]
print((z%M if B else 1))
# Original solution
n, m = list(map(int, input().split()))
pros = sorted([list(map(int, input().split())) for _ in range(m)])
index = 0
covered = 0
right = 0
ans = 0
while True:
  a, b = pros[index]
  if a > covered + 1:
    covered = right
    ans += 1
    continue
  else:
    right = max(right, b)
    index += 1

  if covered == n:
    print(ans)
    break

  if index == m:
    covered = right
    ans += 1
    print((ans if covered == n else "Impossible"))
    break



# Optimized solution
n, m = list(map(int, input().split()))
pros = sorted([list(map(int, input().split())) for _ in range(m)])
index = 0
covered = 0
right = 0
ans = 0
while True:
  a, b = pros[index]
  if a > covered + 1:
    if covered == right:
      print("Impossible")
      break
    covered = right
    ans += 1
    continue
  else:
    right = max(right, b)
    index += 1

  if covered == n:
    print(ans)
    break

  if index == m:
    covered = right
    ans += 1
    print((ans if covered == n else "Impossible"))
    break
# Original solution
import sys
sys.setrecursionlimit(4000)

n = int(eval(input()))
p = [float(x) for x in input().split()]

dp = [[0]*(n+1) for i in range(n)]

dp[0][0] = 1-p[0]
dp[0][1] = p[0]

for i in range(n-1):
  for j in range(i+2):
    dp[i+1][j] += dp[i][j]*(1-p[i+1])
    dp[i+1][j+1] += dp[i][j]*p[i+1]

ans = 0
for i in range(n//2+1, n+1):
  ans += dp[n-1][i]
print(ans)

# Optimized solution
n = int(eval(input()))
p = [float(x) for x in input().split()]

dp = [[0]*(i+2) for i in range(n)]
dp[0][0] = 1-p[0]
dp[0][1] = p[0]

for i in range(1, n):
  for j in range(i+2):
    if j == 0:
      dp[i][j] = dp[i-1][j]*(1-p[i])
      continue
    if j == i+1:
      dp[i][j] = dp[i-1][j-1]*p[i]
      continue
    dp[i][j] = dp[i-1][j-1]*p[i]+dp[i-1][j]*(1-p[i])
ans = 0
for i in range(n//2+1, n+1):
  ans += dp[n-1][i]
print(ans)
# Original solution
n = int(eval(input()))
a = list(map(float, input().split()))

dp = [[0]*(n+1) for i in range(n+1)]
dp[0][0] = 1

for i in range(1,n+1):
  dp[0][i] = 0
  dp[i][0] = dp[i-1][0] * (1 - a[i-1])
  
for i in range(1, n+1):
  for j in range(1, n+1):
    dp[i][j] = dp[i-1][j-1] * a[i-1] + dp[i-1][j] * (1 - a[i-1])

ans = 0
for i in range(n // 2 + 1 , n+1):
  ans += dp[n][i]

print(ans)
  

# Optimized solution
n = int(input())
a = list(map(float, input().split()))
 
dp = [[0]*(n+1) for i in range(n+1)]
dp[0][0] = 1
 
for i in range(1,n+1):
  dp[0][i] = 0
  dp[i][0] = dp[i-1][0] * (1 - a[i-1])
  
for i in range(1, n+1):
  for j in range(1, n+1):
    dp[i][j] = dp[i-1][j-1] * a[i-1] + dp[i-1][j] * (1 - a[i-1])
ans = 0
for i in range(n // 2 + 1 , n+1):
  ans += dp[n][i]

print(ans)
# Original solution
n=int(eval(input()))
import math
p=list(map(float,input().split()))
dp=[[0]*(n) for i in range(n+1)]
dp[0][0]=(1-p[0])
for i in range(1,n):
    dp[0][i]=round(dp[0][i-1]*(1-p[i]),10)
# print(dp[0][1],1-p[2],dp[0][1]*(1-p[2]))
for i in range(1,n+1):
    for j in range(i-1,n):
        if j==0:
            temp1=1 
            temp2=0 
        else:
            temp1=dp[i-1][j-1]
            temp2=dp[i][j-1]
        dp[i][j]=temp1*p[j]+temp2*(1-p[j])
        dp[i][j]=round(dp[i][j],10)
ans=0
# print(dp)
for i in range(n//2+1,n+1):
    ans+=dp[i][n-1]
print(ans)
        

# Optimized solution
n=int(eval(input()))
import math
p=list(map(float,input().split()))
for i in range(n):
    p[i]=p[i]*100
dp=[[0]*(n) for i in range(n+1)]
dp[0][0]=(100-p[0])/100
for i in range(1,n):
    dp[0][i]=dp[0][i-1]*(100-p[i])/100
# print(dp[0][1],1-p[2],dp[0][1]*(1-p[2]))
for i in range(1,n+1):
    for j in range(i-1,n):
        if j==0:
            temp1=1 
            temp2=0 
        else:
            temp1=dp[i-1][j-1]
            temp2=dp[i][j-1]
        dp[i][j]=temp1*p[j]/100+temp2*(100-p[j])/100
        dp[i][j]=dp[i][j]
ans=0
# print(dp)
for i in range(n//2+1,n+1):
    ans+=dp[i][n-1]
print(ans)
# Original solution
N = int(eval(input()))
P = list(map(float,input().split()))

dp = [[0 for j in range(N+1)] for i in range(N)]#i+1枚目までのコインを投げたときにj枚表が出る確率

dp[0][0] = 1-P[0]
dp[0][1] = P[0]
for i in range(1,N):
    dp[i][0] = dp[i-1][0]*(1-P[i])

for i in range(1,N):
    for j in range(1,N+1):
        dp[i][j] = dp[i-1][j-1]*P[i]+dp[i-1][j]*(1-P[i])

ans = 0
for j in range(-(-N//2),N+1):
    ans += dp[N-1][j]
    
print(ans)

# Optimized solution
N = int(eval(input()))
P = list(map(float, input().split()))

dp = [0 for _ in range(N + 1)]
dp[0] = 1

for i in range(N):
    p = P[i]
    for j in range(N)[::-1]:
        dp[j + 1] += dp[j] * p
        dp[j] *= 1 - p

print((sum(dp[N // 2 + 1:])))
# Original solution
N = int(eval(input()))
p = list(map(float, input().split()))

# i-1 まで見たときに表が j 枚出る確率
dp = [[0]*(N+1) for _ in range(N+1)]
dp[0][0] = 1
for i in range(1, N+1):
    for j in range(N+1):
        dp[i][j] += (1-p[i-1])*dp[i-1][j]
        if j >= 1:
            dp[i][j] += p[i-1]*dp[i-1][j-1]

print((sum([dp[N][j] for j in range((N+1)//2, N+1)])))

# Optimized solution
N = int(eval(input()))
p = list(map(float, input().split()))

# i-1 まで見たときに表が j 枚出る確率
dp = [[0]*(N+1) for _ in range(N+1)]
dp[0][0] = 1
for i in range(1, N+1):
    for j in range(N+1):
        dp[i][j] += (1-p[i-1])*dp[i-1][j]
        if j >= 1:
            dp[i][j] += p[i-1]*dp[i-1][j-1]

print((sum([dp[N][N-j] for j in range((N+1)//2)])))
# Original solution
N = int(eval(input()))
P = list(map(float, input().split()))

dp = [0] * (N + 1)
dp[0] = 1
for i in range(1, N + 1):
    tmp = dp
    dp = [0] * (N + 1)
    for j in range(N):
        if j < N:
            dp[j + 1] += tmp[j] * P[i - 1]
        dp[j] += tmp[j] * (1 - P[i - 1])

num = 0
for i in range(N // 2 + 1, N + 1):
    num += dp[i]

print(num)


# Optimized solution
N = int(eval(input()))
P = list(map(float, input().split()))
# dp = [[0] * (N + 1) for i in range(N + 1)]
# dp[0][0] = 1.0
# for i in range(1, N + 1):
#     for j in range(N):
#         if j < N:
#             dp[i][j + 1] += dp[i - 1][j] * P[i - 1]
#         dp[i][j] += dp[i - 1][j] * (1 - P[i - 1])
#
# num = 0
# for i in range(N // 2 + 1, N + 1):
#     num += dp[N][i]
#
# print(num)


dp = [0] * (N + 1)
dp[0] = 1
for i in range(1, N + 1):
    tmp = dp
    dp = [0] * (N + 1)
    for j in range(N):
        if j < N:
            dp[j + 1] += tmp[j] * P[i - 1]
        dp[j] += tmp[j] * (1 - P[i - 1])

num = 0
for i in range(N // 2 + 1, N + 1):
    num += dp[i]

print(num)
# Original solution
N = int(eval(input()))
P = list(map(float, input().split()))
# dp = [[0] * (N + 1) for i in range(N + 1)]
# dp[0][0] = 1.0
# for i in range(1, N + 1):
#     for j in range(N):
#         if j < N:
#             dp[i][j + 1] += dp[i - 1][j] * P[i - 1]
#         dp[i][j] += dp[i - 1][j] * (1 - P[i - 1])
#
# num = 0
# for i in range(N // 2 + 1, N + 1):
#     num += dp[N][i]
#
# print(num)


dp = [0] * (N + 1)
dp[0] = 1
for i in range(1, N + 1):
    tmp = dp
    dp = [0] * (N + 1)
    for j in range(N):
        if j < N:
            dp[j + 1] += tmp[j] * P[i - 1]
        dp[j] += tmp[j] * (1 - P[i - 1])

num = 0
for i in range(N // 2 + 1, N + 1):
    num += dp[i]

print(num)


# Optimized solution
N = int(eval(input()))
P = list(map(float, input().split()))

dp = [0] * (N + 1)
dp[0] = 1
for i in range(1, N + 1):
    tmp = dp
    dp = [0] * (N + 1)
    for j in range(N):
        if j < N:
            dp[j + 1] += tmp[j] * P[i - 1]
        dp[j] += tmp[j] * (1 - P[i - 1])

num = 0
for i in range(N // 2 + 1, N + 1):
    num += dp[i]

print(num)
# Original solution
N = int(eval(input()))
P = list(map(float, input().split()))

"""
dp[i][j]: i枚投げた時にj枚表の確率
"""
dp = [[0] * (N+1) for _ in range(N+1)]
dp[1][0] = 1 - P[0]
dp[1][1] = P[0]

for i in range(1, N+1):
    for j in range(1, N+1):
        dp[i][j] += dp[i-1][j-1] * P[i-1]
        dp[i][j-1] += dp[i-1][j-1] * (1-P[i-1])

ans = 0
for i in range(N+1):
    if N//2 < i:
        ans += dp[N][i]
print(ans)


# Optimized solution
import sys
input = sys.stdin.readline

def main():
    N = int(eval(input()))
    P = list(map(float, input().split()))
    dp = [[0] * (N+1) for _ in range((N+1))]
    dp[0][0] = 1
    for i in range(1, N+1):
        for j in range(i+1):
            dp[i][j] = dp[i-1][j]*(1-P[i-1]) + dp[i-1][j-1]*P[i-1]
    print((sum(dp[N][N//2+1:])))

if __name__ == '__main__':
    main()
# Original solution
# coding: utf-8
import sys
input = sys.stdin.readline

def f2(n, p):
    dp = [ 0.0 ] * (n + 1)
    dp[0] = 1.0
    # pprint.pprint(dp, width = 50)
    for i in range(n):
        dp_ = list(dp)
        pi_ = 1 - p[i]
        for j in range(n + 1):
            dp[j] = dp_[j - 1] * p[i] + dp_[j] * pi_
        # pprint.pprint(dp, width = 50)
    return(sum(dp[n // 2 + 1:]))

n = int(eval(input())) # n: odd, 1 <= n <= 2999
p = list(map(float, input().split())) # 0 < pi[i] < 1
print((f2(n, p)))


# Optimized solution
# coding: utf-8

import sys
input = sys.stdin.readline

def f3(n, p):
    dp = [ 0.0 ] * (n + 1)
    dp[0] = 1.0
    for i in range(n):
        pi_ = 1 - p[i]
        dp = [dp[j - 1] * p[i] + dp[j] * pi_ \
            for j in range(n + 1)]
    return(sum(dp[n // 2 + 1:]))

n = int(eval(input())) # n: odd, 1 <= n <= 2999
p = list(map(float, input().split())) # 0 < pi[i] < 1
print((f3(n, p)))
# Original solution
def f(n):
    ps = list(map(float, input().split()))
    ans = 0
    for b in range(2 ** n):
        if format(b, "b").count("1") > n // 2:
            pi = 1
            for i in range(n):
                if b & 1:
                    pi *= ps[i]
                else:
                    pi *= 1 - ps[i]
                b = b >> 1
            ans += pi
    print(ans)

n = int(eval(input()))
f(n)


# Optimized solution
def f(n):
    ps = list(map(float, input().split()))
    dp = [[1] * (n + 1) for _ in range(n + 1)]
    dpi1 = dp[0]
    for i, p in enumerate(ps):
        i+=1
        dpi = dp[i]
        dpi[0] = dpi1[0] * (1 - p)
        for j in range(1, i):
            dpi[j] = dpi1[j - 1] * p + dpi1[j] * (1 - p)
        dpi[i] = dpi1[i - 1] * p
        dpi1 = dpi
    print((sum(dp[-1][n // 2 + 1:])))

n = int(eval(input()))
f(n)
# Original solution
#Educational DP Contest
#I-Coins

n = int(eval(input()))
lst1 = list(map(float,input().split()))

#dp table
dp = [[0.0]*(n+1) for _ in range(n+1)] #確率を0で初期化(2次元)
dp[0][0] = 1.0 #0番目は存在しないので1で初期化(単位元のような感じ。乗算だから単位元は1)


#process1
#dp[i][j]は、i回までのコインを投げて、j枚が表の確率。
#つまり、ループの内側が表の確率、外側がコインの枚数となる
#但し、i回までのコインでi枚以上の表は出ないので、jのループはi迄とする。
"""
図にするとこんなかんじ(1列目は実際に起きる数字ではない)
[[1.0, 0.0, 0.0, 0.0],
[0.7, 0.3, 0.0, 0.0], #0.7で裏,0.3で表
[0.28, 0.54, 0.18, 0.0],
[0.056, 0.33, 0.468, 0.144]] #0.056+0.33で裏、0.468+0.144で表
"""
for i in range(1,n+1):
    for j in range(i+1):
        dp[i][j] = dp[i-1][j]*(1-lst1[i-1])
        if j > 0:
            dp[i][j] += dp[i-1][j-1]*lst1[i-1]

#output process
#問題はdp[i][j] >= 0.5となる確率なので、j>= 0.5 = 表の枚数/全体の枚数
#となるj以上の確率の合計が答え(ちなみに、任意のdp[i]の合計sum(dp[i]) == 1となる)
ans = 0.0
for i in range((n+1)//2,n+1): #j(表が出る枚数)が半分以上のところから全部のところまでの確率の合計
    ans += dp[-1][i]
print(ans)

# Optimized solution
#Educational DP Contest
#I-Coins

n = int(eval(input()))
lst1 = list(map(float,input().split()))

#dp table
dp = [[0.0]*(n+1) for _ in range(n+1)] #確率を0で初期化(2次元)
dp[0][0] = 1.0 #0番目は存在しないので1で初期化(単位元のような感じ。乗算だから単位元は1)


#process1
#dp[i][j]は、i回までのコインを投げて、j枚が表の確率。
#つまり、ループの内側がn回表の確率、外側がコインの枚数となる
#但し、i回までのコインでi枚以上の表は出ないので、jのループはi迄とする。
"""
図にするとこんなかんじ
    0回表,1回表,2回表...
0枚目[[1.0, 0.0, 0.0, 0.0],
1枚目[0.7, 0.3, 0.0, 0.0], #0.7で1枚中0枚が表,0.3で1枚中1枚が表
2枚目[0.28, 0.54, 0.18, 0.0],
3枚目[0.056, 0.33, 0.468, 0.144]] #0.056+0.33で半分未満が表、0.468+0.144で半分以上が表
"""
for i in range(1,n+1):
    for j in range(i+1): #jはピラミッド状に増えていく
        dp[i][j] = dp[i-1][j]*(1-lst1[i-1]) #裏になる確率
        if j > 0: #j-1を参照できるなら
            dp[i][j] += dp[i-1][j-1]*lst1[i-1] #表になる確率

#output process
#問題はdp[i][j] >= 0.5となる確率なので、j>= 0.5 = 表の枚数/全体の枚数
#となるj以上の確率の合計が答え(ちなみに、任意のdp[i]の合計sum(dp[i]) == 1となる)
ans = 0.0
for i in range((n+1)//2,n+1): #j(表が出る枚数)が半分以上のところから全部のところまでの確率の合計
    ans += dp[-1][i]
print(ans)
# Original solution
N = int(eval(input()))
p = [0] + list(input().split())

for i in range(1, N+1):
    item = p[i].replace('0.', '')
    p[i] = int(item)

dp = [[0 for a in range(3100)] for b in range(3100)]
#dp[i][j] = i枚目までのコインを投げて，表の個数がj枚である確率 * (10**(2*i))

dp[1][0] = 100-p[1]
dp[1][1] = p[1]

for i in range(2, N + 1):
    for j in range(i+1):
        dp[i][j] = dp[i-1][j-1] * p[i] + dp[i-1][j] * (100-p[i])
        #dp[i][j] = i-1枚目までで表がj-1かつi回目で表　＋　i-1回目までで表がj枚かつi回目で裏（MECE）
        #print(i, j, dp[i][j])
        #プログラムの仕組み上，iが一つ進むと，100 * 100 = 10**4　ずつスケールが大きくなっていく


ans = 0

for k in range(-(-N//2), N+1):
    ans += dp[N][k]

print((ans/10**(2 * N)))

# Optimized solution
N = int(eval(input()))
p = [0] + list(map(float, input().split()))

#print(p)

dp = [[0 for a in range(3100)] for b in range(3100)]
#dp[i][j] = i枚目までのコインを投げて，表の個数がj枚である確率

dp[1][0] = 1-p[1]
dp[1][1] = p[1]

for i in range(2, N + 1):
    for j in range(i+1):
        dp[i][j] = (dp[i-1][j-1] * p[i] + dp[i-1][j] * (1-p[i]))
        #dp[i][j] = i-1枚目までで表がj-1かつi回目で表　＋　i-1回目までで表がj枚かつi回目で裏（MECE）
        #print(i, j, dp[i][j])

ans = 0

for k in range(-(-N//2), N+1):
    ans += dp[N][k]

print(ans)
# Original solution
from bisect import bisect_left as bl, bisect_right as br, insort
import sys
import heapq
#from math import *
from collections import defaultdict as dd, deque
def data(): return sys.stdin.buffer.readline().strip().decode()
def mdata(): return list(map(float, data().split()))
out=sys.stdout.write
#sys.setrecursionlimit(100000)
INF=int(1e9)
mod=int(1e9)+7


n=int(data())
P=list(mdata())
dp=[0]*(n//2+2)
dp[1]=1
for i in range(n):
    dp1=dp.copy()
    for j in range(1,len(dp)):
        k=dp[j-1]*(1-P[i])+dp[j]*(P[i])
        dp1[j]=k
    dp=dp1.copy()
print((sum(dp)))




# Optimized solution
from bisect import bisect_left as bl, bisect_right as br, insort
import sys
import heapq
#from math import *
from collections import defaultdict as dd, deque
def data(): return sys.stdin.buffer.readline().strip().decode()
def mdata(): return list(map(float, data().split()))
out=sys.stdout.write
#sys.setrecursionlimit(100000)
INF=int(1e9)
mod=int(1e9)+7


n=int(data())
P=list(mdata())
dp=[0]*(n//2+2)
dp[1]=1
for i in range(n):
    dp1=dp[:]
    for j in range(1,len(dp)):
        k=dp[j-1]*(1-P[i])+dp[j]*(P[i])
        dp1[j]=k
    dp=dp1[:]
print((sum(dp)))
# Original solution
# -*- coding: utf-8 -*-
# from collections import deque
from sys import setrecursionlimit

setrecursionlimit(1000000)


# INF = float("inf")

# d = deque()
# ---Input---#
n = int(eval(input()))
# n, k = map(int, input().split())
p = list(map(float, input().split()))
p = [-1] + p

memo = [[-1 for _ in [0] * (n + 1)] for _ in [0] * (n + 1)]
memo[0][0] = 1
for i in range(len(p))[1:]:
    memo[0][i] = 0
    memo[i][0] = memo[i - 1][0] * (1 - p[i])
memo[0][0] = 1


def dp(i, j):
    if memo[i][j] == -1:
        memo[i][j] = dp(i - 1, j) * (1 - p[i]) + dp(i - 1, j - 1) * p[i]
    return memo[i][j]


ans = 0
tar = int(n / 2) + 1
for i in range(n + 1)[tar:]:
    ans += dp(n, i)


print(("{}".format(ans)))


# Optimized solution
# -*- coding: utf-8 -*-
# from collections import deque
from sys import setrecursionlimit

setrecursionlimit(1000000)


# INF = float("inf")

# d = deque()
# ---Input---#
n = int(eval(input()))
# n, k = map(int, input().split())
p = list(map(float, input().split()))
p = [-1] + p

memo = [[-1 for _ in [0] * (n + 1)] for _ in [0] * (n + 1)]
memo[0][0] = 1
for i in range(len(p))[1:]:
    memo[0][i] = 0
    memo[i][0] = memo[i - 1][0] * (1 - p[i])
memo[0][0] = 1


def dp(i, j):
    if memo[i][j] == -1:
        memo[i][j] = dp(i - 1, j) * (1 - p[i]) + dp(i - 1, j - 1) * p[i]
    return memo[i][j]


ans = 0
tar = int(n / 2) + 1
for i in range(n + 1):
    dp(i, i)
    dp(i, n)

for i in range(n + 1)[tar:]:
    ans += dp(n, i)


print(("{}".format(ans)))
# Original solution
n=int(eval(input()))
p=list(map(float,input().split()))
#dp[i][j] i tells u i coins from 0, j tells u j heads 
#dp[n+1][n+1]
dp=[[0 for i in range(0,n+1)]for j in range(n+1)]

dp[0][0]=1.0
# for i in range(1,n+1):
#     dp[0][i]=0.0
for i in range(1,n+1):
    for j in range(0,n+1):
        if(j==0):
            dp[i][j]=(1.0-p[i-1])*dp[i-1][j]
        else:
            dp[i][j]=p[i-1]*dp[i-1][j-1]+(1.0-p[i-1])*dp[i-1][j]

k=(n//2)+1
ans=0.0
for i in range(k,n+1):
    ans+=dp[n][i]
print(ans)




# Optimized solution
n=int(eval(input()))
p=list(map(float,input().split()))
#dp[i][j] i tells u i coins from 0, j tells u j heads 
#dp[n+1][n+1]
dp=[[0 for i in range(n+1)]for j in range(n+1)]

dp[0][0]=1.0
# for i in range(1,n+1):
#     dp[0][i]=0.0
for i in range(1,n+1):
    for j in range(0,n+1):
        if(j==0):
            dp[i][j]=(1.0-p[i-1])*dp[i-1][j]
        else:
            dp[i][j]=p[i-1]*dp[i-1][j-1]+(1.0-p[i-1])*dp[i-1][j]

k=(n//2)+1
ans=0.0
for i in range(k,n+1):
    ans+=dp[n][i]
print(ans)
# Original solution
N = int(eval(input()))
p = list(map(float, input().split()))
dp = [[0.0 for i in range(N+1)] for j in range(N+1)]
dp[0][0] = 1.0
for i in range(N):
    for j in range(N):
        dp[i+1][j+1] += dp[i][j] * p[i]
        dp[i+1][j] += dp[i][j] * (1 - p[i])
temp = (N+1) // 2
ans = 0
for i in range(temp, N+1):
    ans += dp[N][i]
print(ans)

# Optimized solution
N = int(eval(input()))
p = list(map(float, input().split()))
dp = [[0.0 for i in range(N+1)] for _ in range(N+1)]
dp[0][0] = 1.0
for i in range(N):
    for j in range(i+1):
        # 表が出る
        dp[i+1][j+1] += dp[i][j] * p[i]
        # 裏が出る
        dp[i+1][j] += dp[i][j] * (1 - p[i])
temp = (N+1)//2
print((sum(dp[-1][temp:])))
# Original solution
import collections
N = int(eval(input()))
A = list(map(float,input().split()))
K = N//2  + 1
dp = [[0 for _ in range(N + 1) ] for _ in range(N + 1)]
if N == 0: 
    print((0))
    exit
dp[0][0] = 1
ans = 0
for i in range(1,N+1):
    for j in range(i+1):
        if j - 1 < 0:
            dp[i][j] = dp[i-1][j]*(1-A[i-1])
        else:
            dp[i][j] = dp[i-1][j-1]*A[i-1] + dp[i-1][j]*(1-A[i-1])
#print(dp)
for i in range(K,len(dp[N])):
        ans+=dp[N][i]
print(ans)
        
     

# Optimized solution
import collections
N = int(eval(input()))
A = list(map(float,input().split()))
K = N//2  + 1
dp = [[0 for _ in range(N + 1) ] for _ in range(N + 1)]
if N == 0: 
    print((0))
    exit
dp[0][0] = 1
ans = 0
for i in range(1,N+1):
    for j in range(i+1):
        if j - 1 < 0:
            dp[i][j] = dp[i-1][j]*(1-A[i-1])
        else:
            dp[i][j] = dp[i-1][j-1]*A[i-1] + dp[i-1][j]*(1-A[i-1])
for i in range(K,len(dp[N])):
        ans+=dp[N][i]
print(ans)
# Original solution
from collections import defaultdict as dd    
n=int(eval(input()))
l=list(map(float,input().split()))
dp=[[0]*(n+1) for i in range(n+1)]
dp[0][0]=1
for i in range(1,n+1):
    for j in range(n+1):
        if(j==0):
            dp[i][j]=dp[i-1][j]*(1.0-l[i-1])
        else:
            dp[i][j]=dp[i-1][j]*(1.0-l[i-1])+dp[i-1][j-1]*l[i-1]
ans=0
for i in range(n//2+1,n+1):
    ans+=dp[n][i]
print(ans)

# Optimized solution
import sys
input=sys.stdin.readline
from collections import defaultdict as dd    
n=int(eval(input()))
l=list(map(float,input().split()))
dp=[[0]*(n+1) for i in range(n+1)]
dp[0][0]=1
for i in range(1,n+1):
    for j in range(n+1):
        if(j==0):
            dp[i][j]=dp[i-1][j]*(1.0-l[i-1])
        else:
            dp[i][j]=dp[i-1][j]*(1.0-l[i-1])+dp[i-1][j-1]*l[i-1]
ans=0
for i in range(n//2+1,n+1):
    ans+=dp[n][i]
print(ans)
# Original solution
import sys
from collections import defaultdict
readline = sys.stdin.buffer.readline
sys.setrecursionlimit(10**8)


def geta(fn=lambda s: s.decode()):
    return list(map(fn, readline().split()))


def gete(fn=lambda s: s.decode()):
    return fn(readline().rstrip())


def main():
    N = gete(int)
    # p = tuple(geta(lambda s: int(s.decode()[2:])))
    p = tuple(geta(float))

    cur = [0] * (N + 1)
    cur[0] = 1

    for i, pi in enumerate(p, 1):
        upd = [0] * (N + 1)
        qi = 1 - pi

        upd[0] = cur[0] * qi
        for j in range(1, i + 1):
            upd[j] = cur[j - 1] * pi + cur[j] * qi
        cur = upd

    print((sum(cur[N // 2 + 1:])))


if __name__ == "__main__":
    main()

# Optimized solution
import sys
from collections import defaultdict
readline = sys.stdin.buffer.readline
sys.setrecursionlimit(10**8)


def geta(fn=lambda s: s.decode()):
    return list(map(fn, readline().split()))


def gete(fn=lambda s: s.decode()):
    return fn(readline().rstrip())


def main():
    N = gete(int)
    # p = tuple(geta(lambda s: int(s.decode()[2:])))
    p = tuple(geta(float))

    dp = [[0] * (i + 2) for i in range(N + 1)]
    dp[0][0] = 1

    for i, pi in enumerate(p, 1):
        qi = 1 - pi
        dpi = dp[i]
        dpi1 = dp[i - 1]

        dpi[0] = dpi1[0] * qi

        for j in range(1, i + 1):
            dpi[j] = dpi1[j - 1] * pi + dpi1[j] * qi

    print((sum(dp[N][N // 2 + 1:])))


if __name__ == "__main__":
    main()