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

#include "bits/stdc++.h"
#include <unordered_map>
#include <unordered_set>
#pragma warning(disable : 4996)
using namespace std;
using ld = long double;
const ld eps = 1e-9;

const int dx[4] = {-1, 0, 1, 0};
const int dy[4] = {0, 1, 0, -1};

int dfs(vector<vector<int>> &field, int x, int y, int rest) {
  int ans = 0;
  for (int way = 0; way < 4; ++way) {
    int nowx(x), nowy(y);
    while (1) {
      int nextx = nowx + dx[way];
      int nexty = nowy + dy[way];
      if (field[nexty][nextx] == -1000) {
        break;
      } else if (field[nexty][nextx] <= 0) {
        nowx = nextx;
        nowy = nexty;
        continue;
      } else if (field[nexty][nextx] == 1000) {
        if (rest) {
          nowx = nextx;
          nowy = nexty;
          continue;
        } else {
          ans++;
          break;
        }
      } else {
        field[nexty][nextx] = -field[nexty][nextx];
        ans += dfs(field, nextx, nexty, rest - 1);
        field[nexty][nextx] = -field[nexty][nextx];
        break;
      }
    }
  }
  return ans;
}

int main() {
  while (1) {
    int W, H;
    cin >> W >> H;
    if (!W)
      break;
    vector<vector<int>> field(H + 2, vector<int>(W + 2, -1000));
    int num = 1;
    int sx, sy;
    for (int i = 0; i < H; ++i) {
      for (int j = 0; j < W; ++j) {
        int n;
        cin >> n;
        if (n == 0)
          field[i + 1][j + 1] = 0;
        else if (n == 1)
          field[i + 1][j + 1] = num++;
        else {
          field[i + 1][j + 1] = 1000;
          sx = j + 1;
          sy = i + 1;
        }
      }
    }
    int ans = dfs(field, sx, sy, num - 1);
    cout << ans << endl;
  }

  return 0;
}

Error: MLE

Fixed submission:

#include "bits/stdc++.h"
using namespace std;

int memo[1 << 23][23];
struct aa {
  int x;
  int y;
  int time;
};
const int dx[4] = {-1, 0, 1, 0};
const int dy[4] = {0, 1, 0, -1};
vector<int> getdis(const int now, const vector<vector<int>> &field,
                   const vector<pair<int, int>> &houses) {
  const int sx = houses[now].first;
  const int sy = houses[now].second;

  vector<vector<int>> cans(field.size(), vector<int>(field[0].size()));
  cans[sy][sx] = true;
  for (int way = 0; way < 4; ++way) {
    int nx(sx);
    int ny(sy);
    while (1) {
      nx += dx[way];
      ny += dy[way];
      if (field[ny][nx] && field[ny][nx] != 2) {
        break;
      } else {
        cans[ny][nx] = true;
      }
    }
  }
  vector<int> times;
  for (auto h : houses) {
    times.emplace_back(cans[h.second][h.first]);
  }
  return times;
}
int getans(const int now, bitset<23> &used, vector<vector<int>> &field,
           const vector<pair<int, int>> &houses) {
  if (memo[used.to_ulong()][now] != -1)
    return memo[used.to_ulong()][now];
  if (used.count() == houses.size() - 1) {
    auto vs(getdis(now, field, houses));
    return memo[used.to_ulong()][now] = vs.back();
  } else {
    int sum = 0;
    auto vs(getdis(now, field, houses));
    for (int i = 0; i < houses.size() - 1; ++i) {
      if (vs[i] && !used[i]) {
        used[i] = true;
        field[houses[i].second][houses[i].first] = true;
        const int atime = getans(i, used, field, houses);
        sum += atime;
        field[houses[i].second][houses[i].first] = false;
        used[i] = false;
      }
    }
    return memo[used.to_ulong()][now] = sum;
  }
}

int main() {
  while (1) {
    for (int i = 0; i < (1 << 23); ++i) {
      for (int j = 0; j < 23; ++j) {
        memo[i][j] = -1;
      }
    }
    int M, N;
    cin >> M >> N;
    vector<vector<int>> field(N + 2, vector<int>(M + 2, 3));
    vector<pair<int, int>> houses;
    pair<int, int> rit;
    for (int i = 0; i < N; ++i) {
      for (int j = 0; j < M; ++j) {
        cin >> field[i + 1][j + 1];
        if (field[i + 1][j + 1] == 1) {
          field[i + 1][j + 1] = 0;
          houses.emplace_back(j + 1, i + 1);
        } else if (field[i + 1][j + 1] == 2) {
          rit = make_pair(j + 1, i + 1);
        }
      }
    }
    bitset<23> used(0);
    houses.emplace_back(rit);
    int ans = getans(houses.size() - 1, used, field, houses);
    cout << ans << endl;
  }
  return 0;
}