Problem p03191 (C++)

Buggy submission (status: Memory Limit Exceeded):
#include <bits/stdc++.h>

#define fo(i, a, b) for (int i = a; i <= b; i++)
#define fd(i, a, b) for (int i = a; i >= b; i--)

using namespace std;

typedef long long LL;
typedef double db;

int get() {
  char ch;
  while (ch = getchar(), (ch < '0' || ch > '9') && ch != '-')
    ;
  if (ch == '-') {
    int s = 0;
    while (ch = getchar(), ch >= '0' && ch <= '9')
      s = s * 10 + ch - '0';
    return -s;
  }
  int s = ch - '0';
  while (ch = getchar(), ch >= '0' && ch <= '9')
    s = s * 10 + ch - '0';
  return s;
}

const int N = 605;
const int mo = 1e9 + 7;

int n;
int a[N];
bool bz[N];
bool can[N];
LL f[N][N][N];

LL add(LL x, LL y) { return x + y >= mo ? x + y - mo : x + y; }

int main() {
  n = get();
  fo(i, 1, n * 2) a[i] = get();
  fo(i, 1, n * 2) if (a[i] != -1) bz[a[i]] = 1;
  fo(i, 1, n * 2) can[i] = 1;
  fo(i, 1, n) if (a[i * 2 - 1] != -1 && a[i * 2] != -1) can[a[i * 2 - 1]] =
      can[a[i * 2]] = 0;
  f[n * 2 + 1][0][0] = 1;
  fd(i, n * 2, 1) if (can[i]) {
    if (bz[i]) {
      fo(j, 0, n) fo(k, 0, n) if (f[i + 1][j][k]) {
        //(
        if (j)
          f[i][j - 1][k] = add(f[i][j - 1][k], f[i + 1][j][k]);
        //)
        f[i][j][k + 1] = add(f[i][j][k + 1], f[i + 1][j][k]);
      }
    } else {
      fo(j, 0, n) fo(k, 0, n) if (f[i + 1][j][k]) {
        //(
        if (j)
          f[i][j - 1][k] = add(f[i][j - 1][k], f[i + 1][j][k]);
        if (k)
          f[i][j][k - 1] = (f[i][j][k - 1] + f[i + 1][j][k] * k) % mo;
        //)
        f[i][j + 1][k] = add(f[i][j + 1][k], f[i + 1][j][k]);
      }
    }
  }
  else fo(j, 0, n) fo(k, 0, n) f[i][j][k] = f[i + 1][j][k];
  int cnt = 0;
  fo(i, 1, n) if (a[i * 2 - 1] == -1 && a[i * 2] == -1) cnt++;
  LL ans = f[1][0][0];
  fo(i, 1, cnt) ans = ans * i % mo;
  cout << ans << endl;
  return 0;
}

Fixed submission:
#include <bits/stdc++.h>

#define fo(i, a, b) for (int i = a; i <= b; i++)
#define fd(i, a, b) for (int i = a; i >= b; i--)

using namespace std;

typedef long long LL;
typedef double db;

int get() {
  char ch;
  while (ch = getchar(), (ch < '0' || ch > '9') && ch != '-')
    ;
  if (ch == '-') {
    int s = 0;
    while (ch = getchar(), ch >= '0' && ch <= '9')
      s = s * 10 + ch - '0';
    return -s;
  }
  int s = ch - '0';
  while (ch = getchar(), ch >= '0' && ch <= '9')
    s = s * 10 + ch - '0';
  return s;
}

const int N = 605;
const int mo = 1e9 + 7;

int n;
int a[N];
bool bz[N];
bool can[N];
LL f[N][305][305];

LL add(LL x, LL y) { return x + y >= mo ? x + y - mo : x + y; }

int main() {
  n = get();
  fo(i, 1, n * 2) a[i] = get();
  fo(i, 1, n * 2) if (a[i] != -1) bz[a[i]] = 1;
  fo(i, 1, n * 2) can[i] = 1;
  fo(i, 1, n) if (a[i * 2 - 1] != -1 && a[i * 2] != -1) can[a[i * 2 - 1]] =
      can[a[i * 2]] = 0;
  f[n * 2 + 1][0][0] = 1;
  fd(i, n * 2, 1) if (can[i]) {
    if (bz[i]) {
      fo(j, 0, n) fo(k, 0, n) if (f[i + 1][j][k]) {
        //(
        if (j)
          f[i][j - 1][k] = add(f[i][j - 1][k], f[i + 1][j][k]);
        //)
        f[i][j][k + 1] = add(f[i][j][k + 1], f[i + 1][j][k]);
      }
    } else {
      fo(j, 0, n) fo(k, 0, n) if (f[i + 1][j][k]) {
        //(
        if (j)
          f[i][j - 1][k] = add(f[i][j - 1][k], f[i + 1][j][k]);
        if (k)
          f[i][j][k - 1] = (f[i][j][k - 1] + f[i + 1][j][k] * k) % mo;
        //)
        f[i][j + 1][k] = add(f[i][j + 1][k], f[i + 1][j][k]);
      }
    }
  }
  else fo(j, 0, n) fo(k, 0, n) f[i][j][k] = f[i + 1][j][k];
  int cnt = 0;
  fo(i, 1, n) if (a[i * 2 - 1] == -1 && a[i * 2] == -1) cnt++;
  LL ans = f[1][0][0];
  fo(i, 1, cnt) ans = ans * i % mo;
  cout << ans << endl;
  return 0;
}