Problem:
Score : 100 points

Problem Statement

Let N be a positive odd number.

There are N coins, numbered 1, 2, \ldots, N.
For each i (1 \leq i \leq N), when Coin i is tossed, it comes up heads with probability p_i and tails with probability 1 - p_i.

Taro has tossed all the N coins.
Find the probability of having more heads than tails.

Constraints

N is an odd number.

1 \leq N \leq 2999

p_i is a real number and has two decimal places.

0 < p_i < 1

Input

Input is given from Standard Input in the following format:

N
p_1 p_2 \ldots p_N

Output

Print the probability of having more heads than tails.
The output is considered correct when the absolute error is not greater than 10^{-9}.

Sample Input 1

3
0.30 0.60 0.80

Sample Output 1

0.612

The probability of each case where we have more heads than tails is as follows:

The probability of having (Coin 1, Coin 2, Coin 3) = (Head, Head, Head) is 0.3 × 0.6 × 0.8 = 0.144;

The probability of having (Coin 1, Coin 2, Coin 3) = (Tail, Head, Head) is 0.7 × 0.6 × 0.8 = 0.336;

The probability of having (Coin 1, Coin 2, Coin 3) = (Head, Tail, Head) is 0.3 × 0.4 × 0.8 = 0.096;

The probability of having (Coin 1, Coin 2, Coin 3) = (Head, Head, Tail) is 0.3 × 0.6 × 0.2 = 0.036.

Thus, the probability of having more heads than tails is 0.144 + 0.336 + 0.096 + 0.036 = 0.612.

Sample Input 2

1
0.50

Sample Output 2

0.5

Outputs such as 0.500, 0.500000001 and 0.499999999 are also considered correct.

Sample Input 3

5
0.42 0.01 0.42 0.99 0.42

Sample Output 3

0.3821815872

Solution in Haskell (GHC 7.10.3) (judge verdict: Accepted)

{-# LANGUAGE BangPatterns #-}
import Control.Arrow
import Control.Monad.Fix
import Data.Int
import Data.Foldable
import qualified Data.Vector as V
import qualified Data.Vector.Unboxed as VU
import qualified Data.ByteString.Char8 as B
import Debug.Trace

iscanl :: (Int -> a -> b -> a) -> a -> V.Vector b -> V.Vector a
iscanl !k !a !v = V.scanl' (\(!x) (!i, !v) -> k i x v) a (V.indexed v)

iscanlU
  :: (VU.Unbox a, VU.Unbox b)
  => (Int -> a -> b -> a)
  -> a
  -> VU.Vector b
  -> VU.Vector a
iscanlU !k !a !v = VU.scanl' (\(!x) (!i, !v) -> k i x v) a (VU.indexed v)

ipostscanlU
  :: (VU.Unbox a, VU.Unbox b)
  => (Int -> a -> b -> a)
  -> a
  -> VU.Vector b
  -> VU.Vector a
ipostscanlU !k !a !v = iscanlU (\(!i) (!a) (!b) -> k (i + 1) a b)
                               (k 0 a (VU.unsafeHead v))
                               (VU.unsafeTail v)

solve :: Int -> VU.Vector Int -> Double
solve !n !pn = VU.sum $ VU.drop ((n + 1) `div` 2) $ V.last dp
 where
  dp :: V.Vector (VU.Vector Double)
  dp =
    iscanl
        ( \(!i) (!prev) (!pint) -> VU.generate
          (i + 2)
          ( \(!j) ->
            let pi = fromIntegral pint / 100
                qi = 1 - pi
            in  (if j == 0 then 0 else prev VU.! (j - 1) * pi)
                  + (if i + 1 == j then 0 else prev VU.! j * qi)
          )
        )
        (VU.singleton 1)
      $ V.convert pn

main = do
  let readInt :: Integral a => B.ByteString -> Maybe (a, B.ByteString)
      readInt = fmap (first fromIntegral . second B.tail) . B.readInt
  let readDouble :: Integral a => B.ByteString -> Maybe (a, B.ByteString)
      readDouble b = readInt $ B.drop 2 b

  n  <- (\vec -> (vec VU.! 0)) . VU.unfoldrN 1 readInt <$> B.getLine
  pn <- VU.unfoldrN n readDouble <$> B.getLine
  print $ solve n pn