unittest
{
	assert( [ "5 100 90 80", "98", "40", "30", "21", "80" ].parse.expand.solve == 23 );
	assert( [ "8 100 90 80", "100", "100", "90", "90", "90", "80", "80", "80" ].parse.expand.solve == 0 );
	assert( [ "8 1000 800 100", "300", "333", "400", "444", "500", "555", "600", "666" ].parse.expand.solve == 243 );
}



import std.algorithm;
import std.conv;
import std.math;
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 ) )
{
	auto nabc = input.front.split.to!( long[] );
	auto ls = new long[ nabc[ 0 ] ];
	foreach( ref l; ls )
	{
		input.popFront;
		l = input.front.to!( long );
	}
	
	return tuple( nabc[ 1 ], nabc[ 2 ], nabc[ 3 ], ls );
}

auto solve( long a, long b, long c, long[] ls )
{
	return dfs( a, b, c, 0, 0, 0, ls );
}

long dfs( long la, long lb, long lc, long ca, long cb, long cc, long[] ls )
{
	if( ls.length == 0 )
	{
		// 延長、縮小したときのコストを計算
		if( ca == 0 || cb == 0 || cc == 0 ) return long.max - 100;					// 1本も選んでなかったらダメ
		else                                return la.abs + lb.abs + lc.abs;
	}
	
	// 合成したときのコストを計算
	auto cs = new long[ 4 ];
	cs[ 0 ] = dfs( la,           lb,           lc,           ca    , cb    , cc    , ls[ 1 .. $ ] );							// この竹を使わないとき
	cs[ 1 ] = dfs( la - ls[ 0 ], lb,           lc,           ca + 1, cb    , cc    , ls[ 1 .. $ ] ) + ( ca == 0 ? 0 : 10 );		// この竹をAに合成したとき（1本目だったら合成コスト足さない）
	cs[ 2 ] = dfs( la,           lb - ls[ 0 ], lc,           ca    , cb + 1, cc    , ls[ 1 .. $ ] ) + ( cb == 0 ? 0 : 10 );		// この竹をBに合成したとき（1本目だったら合成コスト足さない）
	cs[ 3 ] = dfs( la,           lb,           lc - ls[ 0 ], ca    , cb    , cc + 1, ls[ 1 .. $ ] ) + ( cc == 0 ? 0 : 10 );		// この竹をCに合成したとき（1本目だったら合成コスト足さない）
	return cs.reduce!min;
}
