Problem p03516 (C++)

Buggy submission (status: Runtime Error):
#include <algorithm>
#include <cmath>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <iostream>
using namespace std;

const int N = 309;
const int mod = 1000000007;

int n, ans, i2;
int dp[N][N][N * 2], d[N], fac[N], inv[N];

int quickpow(int x, int y) {
  int s = 1;
  for (; y; y >>= 1, x = 1ll * x * x % mod)
    if (y & 1)
      s = 1ll * s * x % mod;
  return s;
}

void init() {
  int i;
  fac[0] = fac[1] = inv[0] = inv[1] = 1;
  for (i = 2; i <= n + n; i++)
    fac[i] = 1ll * fac[i - 1] * i % mod;
  inv[n + n] = quickpow(fac[n + n], mod - 2);
  for (i = n + n - 1; i; i--)
    inv[i] = 1ll * inv[i + 1] * (i + 1) % mod;
}

void add(int &x, int y) {
  x += y;
  (x >= mod) ? x -= mod : 0;
}

int main() {
  int i, j, k;
  scanf("%d", &n);
  for (i = 0; i < n; i++)
    scanf("%d", &d[i]);
  init();
  dp[0][0][0] = 1;
  for (i = 0; i < n; i++)
    for (j = 0; j <= i; j++)
      for (k = 0; k <= n + n; k++) {
        if (!dp[i][j][k])
          continue;
        add(dp[i + 1][j][k], 1ll * dp[i][j][k] * inv[d[i] - 1] % mod);
        if (d[i] >= 2 && k + d[i] - 2 <= n + n)
          add(dp[i + 1][j + 1][k + d[i] - 2],
              1ll * dp[i][j][k] * inv[d[i] - 2] % mod);
      }
  i2 = quickpow(2, mod - 2);
  for (j = 3; j <= n; j++)
    for (k = 0; k <= n + n; k++) {
      if (!dp[n][j][k])
        continue;
      if (j < n && k == 0)
        continue;
      if (j == n && k == 0) {
        add(ans, 1ll * dp[n][j][k] * i2 % mod * fac[n - 1] % mod);
        continue;
      }
      if (j < n)
        add(ans, 1ll * dp[n][j][k] * k % mod * fac[j - 1] % mod *
                     fac[n - j - 1] % mod * i2 % mod);
    }
  printf("%d\n", ans);
  return 0;
}

Fixed submission:
#include <algorithm>
#include <cmath>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <iostream>
using namespace std;

const int N = 309;
const int mod = 1000000007;

int n, ans, i2;
int dp[N][N][N * 2], d[N], fac[N * 2], inv[N * 2];

int quickpow(int x, int y) {
  int s = 1;
  for (; y; y >>= 1, x = 1ll * x * x % mod)
    if (y & 1)
      s = 1ll * s * x % mod;
  return s;
}

void init() {
  int i;
  fac[0] = fac[1] = inv[0] = inv[1] = 1;
  for (i = 2; i <= n + n; i++)
    fac[i] = 1ll * fac[i - 1] * i % mod;
  inv[n + n] = quickpow(fac[n + n], mod - 2);
  for (i = n + n - 1; i; i--)
    inv[i] = 1ll * inv[i + 1] * (i + 1) % mod;
}

void add(int &x, int y) {
  x += y;
  (x >= mod) ? x -= mod : 0;
}

int main() {
  int i, j, k;
  scanf("%d", &n);
  for (i = 0; i < n; i++)
    scanf("%d", &d[i]);
  init();
  dp[0][0][0] = 1;
  for (i = 0; i < n; i++)
    for (j = 0; j <= i; j++)
      for (k = 0; k <= n + n; k++) {
        if (!dp[i][j][k])
          continue;
        add(dp[i + 1][j][k], 1ll * dp[i][j][k] * inv[d[i] - 1] % mod);
        if (d[i] >= 2 && k + d[i] - 2 <= n + n)
          add(dp[i + 1][j + 1][k + d[i] - 2],
              1ll * dp[i][j][k] * inv[d[i] - 2] % mod);
      }
  i2 = quickpow(2, mod - 2);
  for (j = 3; j <= n; j++)
    for (k = 0; k <= n + n; k++) {
      if (!dp[n][j][k])
        continue;
      if (j < n && k == 0)
        continue;
      if (j == n && k == 0) {
        add(ans, 1ll * dp[n][j][k] * i2 % mod * fac[n - 1] % mod);
        continue;
      }
      if (j < n)
        add(ans, 1ll * dp[n][j][k] * k % mod * fac[j - 1] % mod *
                     fac[n - j - 1] % mod * i2 % mod);
    }
  printf("%d\n", ans);
  return 0;
}