Problem p03174 (C++)

Buggy submission (status: Memory Limit Exceeded):
// Author : Siriuslight
#include "bits/stdc++.h"
#include "ext/pb_ds/assoc_container.hpp"
#include "ext/pb_ds/tree_policy.hpp"
#define FIO                                                                    \
  ios_base::sync_with_stdio(false), cin.tie(0), cout.tie(0),                   \
      cout << setprecision(10) << fixed;
#define int long long
#define F first
#define S second

using namespace std;
using namespace __gnu_pbds;

#define TRACE
#ifdef TRACE
#define trace(...) __f(#__VA_ARGS__, __VA_ARGS__)
template <typename Arg1> void __f(const char *name, Arg1 &&arg1) {
  cerr << name << " : " << arg1 << std::endl;
}
template <typename Arg1, typename... Args>
void __f(const char *names, Arg1 &&arg1, Args &&...args) {
  const char *comma = strchr(names + 1, ',');
  cerr.write(names, comma - names) << " : " << arg1 << " | ";
  __f(comma + 1, args...);
}
#else
#define trace(...)
#endif

typedef long long ll;
typedef long double ld;
typedef tree<ll, null_type, less<ll>, rb_tree_tag,
             tree_order_statistics_node_update>
    ordered_set;

const ll inf = 1e9 + 100, N = 23;
const ll INF = 1e18 + 100, MOD = 1e9 + 7;

ll powmod(ll a, ll b, ll m = MOD) {
  ll r = 1;
  while (b > 0) {
    if (b & 1)
      r = r * a % m;
    a = a * a % m;
    b >>= 1;
  }
  return r;
}
ll power(ll a, ll b) {
  ll r = 1;
  while (b > 0) {
    if (b & 1)
      r = r * a;
    a = a * a;
    b >>= 1;
  }
  return r;
}
ll gcd(ll a, ll b) {
  if (!b)
    return a;
  return gcd(b, a % b);
}
ll inv(ll a, ll m = MOD) { return powmod(a, m - 2, m); }
ll lcm(ll a, ll b) { return (a * b) / gcd(a, b); }

// ordered_set X;
// X.insert(3);
// X.order_of_key(3) no of elements less than 3
//*X.find_by_order(n) nth greatest element(0-indexed)

int n, a[N][N], dp[1LL << N][N];

int solve(int mask, int id) {
  if (id == 0) {
    return mask == ((1LL << (n + 1)) - 1);
  }
  int &res = dp[mask][id];
  if (res != -1)
    return res;
  res = 0;
  for (int j = 1; j <= n; ++j) {
    if (a[id][j] == 1 && ((mask >> j) & 1) == 0) {
      res += solve(mask | (1LL << j), id - 1);
      res %= MOD;
    }
  }
  return res;
}

int32_t main() {
  FIO;
  cin >> n;
  for (int i = 1; i <= n; ++i) {
    for (int j = 1; j <= n; ++j) {
      cin >> a[i][j];
    }
  }
  memset(dp, -1, sizeof(dp));
  cout << solve(1, n);
}


Fixed submission:
// Author : Siriuslight
#include "bits/stdc++.h"
#include "ext/pb_ds/assoc_container.hpp"
#include "ext/pb_ds/tree_policy.hpp"
#define FIO                                                                    \
  ios_base::sync_with_stdio(false), cin.tie(0), cout.tie(0),                   \
      cout << setprecision(10) << fixed;
// #define int long long
#define F first
#define S second

using namespace std;
using namespace __gnu_pbds;

#define TRACE
#ifdef TRACE
#define trace(...) __f(#__VA_ARGS__, __VA_ARGS__)
template <typename Arg1> void __f(const char *name, Arg1 &&arg1) {
  cerr << name << " : " << arg1 << std::endl;
}
template <typename Arg1, typename... Args>
void __f(const char *names, Arg1 &&arg1, Args &&...args) {
  const char *comma = strchr(names + 1, ',');
  cerr.write(names, comma - names) << " : " << arg1 << " | ";
  __f(comma + 1, args...);
}
#else
#define trace(...)
#endif

typedef long long ll;
typedef long double ld;
typedef tree<ll, null_type, less<ll>, rb_tree_tag,
             tree_order_statistics_node_update>
    ordered_set;

const ll inf = 1e9 + 100, N = 23;
const ll INF = 1e18 + 100, MOD = 1e9 + 7;

ll powmod(ll a, ll b, ll m = MOD) {
  ll r = 1;
  while (b > 0) {
    if (b & 1)
      r = r * a % m;
    a = a * a % m;
    b >>= 1;
  }
  return r;
}
ll power(ll a, ll b) {
  ll r = 1;
  while (b > 0) {
    if (b & 1)
      r = r * a;
    a = a * a;
    b >>= 1;
  }
  return r;
}
ll gcd(ll a, ll b) {
  if (!b)
    return a;
  return gcd(b, a % b);
}
ll inv(ll a, ll m = MOD) { return powmod(a, m - 2, m); }
ll lcm(ll a, ll b) { return (a * b) / gcd(a, b); }

// ordered_set X;
// X.insert(3);
// X.order_of_key(3) no of elements less than 3
//*X.find_by_order(n) nth greatest element(0-indexed)

int n, a[N][N], dp[1LL << N][N];

int solve(int mask, int id) {
  if (id == 0) {
    return mask == ((1LL << (n + 1)) - 1);
  }
  int &res = dp[mask][id];
  if (res != -1)
    return res;
  res = 0;
  for (int j = 1; j <= n; ++j) {
    if (a[id][j] == 1 && ((mask >> j) & 1) == 0) {
      res += solve(mask | (1LL << j), id - 1);
      res %= MOD;
    }
  }
  return res;
}

int32_t main() {
  FIO;
  cin >> n;
  for (int i = 1; i <= n; ++i) {
    for (int j = 1; j <= n; ++j) {
      cin >> a[i][j];
    }
  }
  memset(dp, -1, sizeof(dp));
  cout << solve(1, n);
}