unittest
{
	assert( [ "3", "0.30 0.60 0.80" ].parse.expand.solve == "0.612000000" );
	assert( [ "1", "0.50" ].parse.expand.solve == "0.500000000" );
	assert( [ "5", "0.42 0.01 0.42 0.99 0.42" ].parse.expand.solve == "0.382181587" );
	
	assert( [ "2", "0.50 0.50" ].parse.expand.solve == "0.250000000" );		// 追加ケース
}



import std.conv;
import std.format;
import std.range;
import std.stdio;
import std.typecons;

void main()
{
	stdin.byLineCopy.parse.expand.solve.writeln;
}

auto parse( Range )( Range input )
if( isInputRange!Range && is( ElementType!Range == string ) )
{
	input.popFront;
	auto ps = input.front.split.to!( real[] );
	return tuple( ps );
}

auto solve( real[] ps )
{
	// dp[ 表の枚数 ][ 裏の枚数 ] = この状況になる確率
	auto dp = new real[][]( 1 + ps.length, 1 + ps.length );
	foreach( ref dpp; dp ) dpp[] = 0;
	dp[ 0 ][ 0 ] = 1;
	foreach( i; 0L .. ps.length.signed )
	{
		foreach( j; 0L .. ps.length.signed - i )
		{
			dp[ i + 1 ][ j ] += dp[ i ][ j ] * ps[ i + j ];
			dp[ i ][ j + 1 ] += dp[ i ][ j ] * ( 1 - ps[ i + j ] );
		}
	}
	
	// 表のほうが多い確率を合計
	auto ans = 0.0L;
	foreach( i; ps.length.signed / 2 + 1 .. ps.length.signed + 1 )
	{
		ans += dp[ i ][ ps.length.signed - i ];
	}
	return format( "%0.9f", ans );
}
