Problem p01724 (C++) — buggy submission, verdict: Memory Limit Exceeded

#include <bits/stdc++.h>
#define FOR(i, k, n) for (int i = (k); i < int(n); ++i)
#define REP(i, n) FOR(i, 0, n)
#define ALL(x) begin(x), end(x)

using namespace std;
constexpr int INF = 30;

map<pair<int, int>, int8_t> memo;

int8_t dfs(const vector<vector<int>> &idx, int i, int j) {
  auto itr = memo.find(make_pair(i, j));
  if (itr != end(memo))
    return itr->second;
  if (j == 15 * 19)
    return 0;
  int oi = j / 15;
  int oj = j % 15;
  int di[8] = {1, 1, 1, 0, -1, -1, -1, 0};
  int dj[8] = {-1, 0, 1, 1, 1, 0, -1, -1};
  int8_t res = INF;
  REP(k, 8) {
    int l = 1;
    vector<int> ei;
    int ni;
    int nj;
    while (1) {
      ni = oi + l * di[k];
      nj = oj + l * dj[k];
      if (ni < 0 || ni >= 19 || nj < 0 || nj >= 15)
        break;
      if (idx[ni][nj] < 0 || ((i >> idx[ni][nj]) & 1))
        break;
      ei.push_back(idx[ni][nj]);
      ++l;
    }
    if (l > 1) {
      int pi = i;
      for (int ix : ei) {
        pi |= 1 << ix;
      }
      if (ni >= 19 || (ni == 18 && nj >= 0 && nj < 15)) {
        res = min(res, int8_t(dfs(idx, pi, 15 * 19) + 1));
      } else if (ni >= 0 && nj >= 0 && nj < 15) {
        res = min(res, int8_t(dfs(idx, pi, ni * 15 + nj) + 1));
      }
    }
  }
  memo[make_pair(i, j)] = res;
  return res;
}

int main() {
  vector<string> t(19);
  vector<pair<int, int>> vb;
  vector<vector<int>> idx(19, vector<int>(15, -1));
  int si, sj;
  REP(i, 19) {
    cin >> t[i];
    REP(j, 15) {
      if (t[i][j] == 'X') {
        idx[i][j] = vb.size();
        vb.emplace_back(i, j);
      } else if (t[i][j] == 'O') {
        si = i;
        sj = j;
      }
    }
  }
  int res = dfs(idx, 0, si * 15 + sj);
  if (res < INF) {
    cout << (int)res << endl;
  } else {
    cout << -1 << endl;
  }
  return 0;
}

Error: MLE

Fixed submission:

#include <bits/stdc++.h>
#define FOR(i, k, n) for (int i = (k); i < int(n); ++i)
#define REP(i, n) FOR(i, 0, n)
#define ALL(x) begin(x), end(x)

using namespace std;
constexpr int INF = 30;

int main() {
  vector<string> t(19);
  vector<pair<int, int>> vb;
  vector<vector<int>> idx(19, vector<int>(15, -1));
  int si, sj;
  REP(i, 19) {
    cin >> t[i];
    REP(j, 15) {
      if (t[i][j] == 'X') {
        idx[i][j] = vb.size();
        vb.emplace_back(i, j);
      } else if (t[i][j] == 'O') {
        si = i;
        sj = j;
      }
    }
  }
  int n = vb.size();
  vector<vector<int8_t>> dp(1 << n, vector<int8_t>(15 * 19 + 1, INF));
  dp[0][si * 15 + sj] = 0;
  REP(i, 1 << n) {
    REP(j, 15 * 19) {
      if (dp[i][j] == INF)
        continue;
      int oi = j / 15;
      int oj = j % 15;
      int di[8] = {1, 1, 1, 0, -1, -1, -1, 0};
      int dj[8] = {-1, 0, 1, 1, 1, 0, -1, -1};
      REP(k, 8) {
        int l = 1;
        vector<int> ei;
        int ni;
        int nj;
        while (1) {
          ni = oi + l * di[k];
          nj = oj + l * dj[k];
          if (ni < 0 || ni >= 19 || nj < 0 || nj >= 15)
            break;
          if (idx[ni][nj] < 0 || ((i >> idx[ni][nj]) & 1))
            break;
          ei.push_back(idx[ni][nj]);
          ++l;
        }
        if (l > 1) {
          int pi = i;
          for (int ix : ei) {
            pi |= 1 << ix;
          }
          if (ni >= 19) {
            dp[pi][15 * 19] = min(dp[pi][15 * 19], int8_t(dp[i][j] + 1));
          } else if (ni >= 0 && nj >= 0 && nj < 15) {
            dp[pi][ni * 15 + nj] =
                min(dp[pi][ni * 15 + nj], int8_t(dp[i][j] + 1));
          }
        }
      }
    }
  }
  int8_t res = INF;
  REP(i, 1 << n) res = min(res, dp[i][15 * 19]);
  if (res < INF) {
    cout << (int)res << endl;
  } else {
    cout << -1 << endl;
  }
  return 0;
}