Problem:
Score : 1000 points

Problem Statement

Snuke has come up with the following problem.

You are given a sequence d of length N.
Find the number of the undirected graphs with N vertices labeled 1,2,...,N satisfying the following conditions, modulo 10^{9} + 7:

The graph is simple and connected.

The degree of Vertex i is d_i.

When 2 \leq N, 1 \leq d_i \leq N-1, {\rm Σ} d_i = 2(N-1), it can be proved that the answer to the problem is \frac{(N-2)!}{(d_{1} -1)!(d_{2} - 1)! ... (d_{N}-1)!}.

Snuke is wondering what the answer is when 3 \leq N, 1 \leq d_i \leq N-1, { \rm Σ} d_i = 2N.
Solve the problem under this condition for him.

Constraints

3 \leq N \leq 300

1 \leq d_i \leq N-1

{ \rm Σ} d_i = 2N

Partial Scores

In the test set worth 200 points, N \leq 5.

In the test set worth another 200 points, N \leq 18.

In the test set worth another 300 points, N \leq 50.

Input

Input is given from Standard Input in the following format:

N
d_1 d_2 ... d_{N}

Output

Print the answer.

Sample Input 1

5
1 2 2 3 2

Sample Output 1

6

There are six graphs as shown below:

Sample Input 2

16
2 1 3 1 2 1 4 1 1 2 1 1 3 2 4 3

Sample Output 2

555275958

Be sure to find the answer modulo 10^{9} + 7.

Solution in C++14 (GCC 5.4.1) (judge verdict: Wrong Answer)

#include <bits/stdc++.h>
using namespace std;
typedef long long lint;
typedef long double llf;
typedef pair<int, int> pi;
const int mod = 1e9 + 7;
const int MAXN = 305;

lint ipow(lint x, lint p){
	lint ret = 1, piv = x % mod;
	while(p){
		if(p&1) ret *= piv;
		piv *= piv;
		ret %= mod;
		piv %= mod;
		p >>= 1;
	}
	return ret % mod;
}

int n, d[MAXN];
lint fact[MAXN], invf[MAXN];
lint dp[MAXN][MAXN][MAXN];

lint f(int x, int y, int z){
	if(x == n) return (y == 0 && z == 0);
	if(y < 0 || z < 0) return 0;
	if(~dp[x][y][z]) return dp[x][y][z];
	lint ans = f(x + 1, y, z);
	if(d[x] > 1) ans += f(x + 1, y - 1, z - (d[x] - 2)) * (d[x] - 1);
	ans %= mod;
	return dp[x][y][z] = ans;
}

int main(){
	fact[0] = 1;
	for(int i=1; i<MAXN; i++) fact[i] = fact[i-1] * i % mod;
	for(int i=0; i<MAXN; i++) invf[i] = ipow(fact[i], mod-2);
	cin >> n;
	for(int i=0; i<n; i++) cin >> d[i];
	if(count(d, d + n, 2) == n){
		cout << fact[n-1] * ipow(2, mod - 2) % mod<< endl;
		return 0;
	}
	memset(dp, -1, sizeof(dp));
	lint ret = 0;
	for(int i=3; i<=n; i++){
		for(int j=1; j<=n; j++){
			lint ans = fact[n - 1 - i] * fact[i - 1] % mod;
			ans *= j;
			ans %= mod;
			ans *= f(0, i, j);
			ans %= mod;
			ret += ans;
		}
	}
	/*
	for(int i=1; i<(1<<n); i++){
		int ndg = 0, cnt = 0;
		lint ans = 1;
		for(int j=0; j<n; j++){
			if((i >> j) & 1){
				ans *= d[j] - 1;
				ans %= mod;
				cnt++;
				ndg += d[j] - 2;
			}
		}
		lint ans = fact[n - 1 - cnt] * fact[cnt - 1] % mod;
		ans *= ndg;
		ans %= mod;
		ret += ans;
	}*/
	for(int j=0; j<n; j++) ret *= invf[d[j] - 1], ret %= mod;
	ret %= mod;
	ret *= (mod + 1) / 2;
	cout << ret % mod << endl;
}