import std.stdio, std.conv, std.string, std.bigint;
import std.math, std.random, std.datetime;
import std.array, std.range, std.algorithm, std.container, std.format;
string read(){ static string[] ss; while(!ss.length) ss = readln.chomp.split; string res = ss[0]; ss.popFront; return res; }

/*

確率漸化式
確率DP 期待値DP
小数 近似値 絶対誤差 format

個数の分布だけを考えればよい
3個の皿がi個、2個の皿がj個、1個の皿がk個（、0個の皿がl個）であるときの残り回数の期待値を

x[i][j][k]

とすると

x[i][j][k] = 1
	+	(i / n) * x[i - 1][j + 1][k]
	+ (j / n) * x[i][j - 1][k + 1]
	+ (k / n) * x[i][j][k - 1]
	+ (l / n) * x[i][j][k]

だから

(1 - l / n) x[i][j][k] = n / n
	+	(i / n) * x[i - 1][j + 1][k]
	+ (j / n) * x[i][j - 1][k + 1]
	+ (k / n) * x[i][j][k - 1]

(i + j + k) x[i][j][k] = n + i * x[i - 1][j + 1][k] + j * x[i][j - 1][k + 1] + k * x[i][j][k - 1]

i、j、kの降順でDPでもできそうだが、メモ化再帰が書きやすそう

*/

void main(){
	int n = read.to!int;
	
	int x, y, z;
	foreach(i; 0 .. n){
		int a = read.to!int;
		if(a == 3) x += 1;
		else if(a == 2) y += 1;
		else z += 1;
	}
	
	real[int] memo;
	real solve(int i, int j, int k){
		if(i + j + k == 0) return 0.0;
		
		int key = i * (n * n + 10) + j * (n + 10) + k;
		if(key !in memo){
			real res = n;
			if(i > 0) res += i * solve(i - 1, j + 1, k);
			if(j > 0) res += j * solve(i, j - 1, k + 1);
			if(k > 0) res += k * solve(i, j, k - 1);
			memo[key] = res / (i + j + k);
		}
		
		return memo[key];
		
	}
	
	real ans = solve(x, y, z);
	
	format("%12.12f", ans).writeln;
	
}
