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

#include <cstdio>
#include <iostream>
#include <map>
#include <vector>
using namespace std;
#define rep(i, n) for (int i = 0; i < n; i++)
#define END (64)
#define EMPTY (-2)
#define WALL (-1)
int px[24], py[24], kx, ky;
int H, W, N;
int field[12][12];

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

map<int, int> memo[24];

int dfs(int pos, int bit, bool done[12][12]) {
  if (memo[pos].find(bit) != memo[pos].end())
    return memo[pos][bit];

  // SÌÆÉHÁ½ã³ïÉAêé©Ç¤©
  if (bit == (1 << N) - 1) {
    rep(d, 4) {
      int cx = px[pos] + dx[d], cy = py[pos] + dy[d];
      while (field[cy][cx] != WALL) {
        if (field[cy][cx] == END)
          return 1;
        cy += dy[d], cx += dx[d];
      }
    }
    return 0;
  }

  // »êÈOÈçHÁÄÈ¢ÆÅÅÉ·éÆð©Â¯éB
  int ans = 0;
  rep(d, 4) {
    int cx = px[pos] + dx[d], cy = py[pos] + dy[d];
    while (field[cy][cx] == EMPTY || field[cy][cx] == END ||
           done[cy][cx] == true) {
      cy += dy[d], cx += dx[d];
    }
    if (field[cy][cx] != -1) {
      done[cy][cx] = 1;
      ans += dfs(field[cy][cx], bit | (1 << field[cy][cx]), done);
      done[cy][cx] = 0;
    }
  }

  // HÁ½ÆÌª19¢ÈçéB(Îô)
  if (__builtin_popcount(bit) < 19)
    memo[pos][bit] = ans;
  return ans;
}

int main() {
  while (cin >> W >> H, W) {
    // ú»
    N = 0;
    rep(i, 12) rep(j, 12) field[i][j] = WALL;

    // üÍ
    rep(i, H) rep(j, W) {
      int t;
      cin >> t;
      switch (t) {
      case 0:
        field[i + 1][j + 1] = EMPTY;
        break;
      case 1:
        field[i + 1][j + 1] = N;
        px[N] = j + 1, py[N] = i + 1;
        N++;
        break;
      case 2:
        kx = j + 1, ky = i + 1;
        field[i + 1][j + 1] = END;
        break;
      }
    }
    px[N] = kx, py[N] = ky;

    // Tõ
    rep(i, 24) memo[i].clear();
    bool done[12][12] = {{false}};
    cout << dfs(N, 0, done) << endl;
  }
}

Error: MLE

Fixed submission:

#include <cstdio>
#include <iostream>
#include <map>
#include <vector>
using namespace std;
#define rep(i, n) for (int i = 0; i < n; i++)

int px[24], py[24], kx, ky;
int num[24][4] = {0};

int H, W, N, ans;
int field[12][12] = {0};

int dx[] = {0, -1, 0, 1}, dy[] = {1, 0, -1, 0};
bool done[12][12];

map<int, int> memo[24];

int dfs(int pos, int bit) {
  if (memo[pos].find(bit) != memo[pos].end())
    return memo[pos][bit];
  if (bit == (1 << N) - 1) {
    rep(d, 4) {
      int cx = px[pos] + dx[d], cy = py[pos] + dy[d];
      while (field[cy][cx] != -1) {
        if (field[cy][cx] == 64)
          return 1;
        cy += dy[d], cx += dx[d];
      }
    }
    return 0;
  }
  int ans = 0;
  rep(d, 4) {
    int cx = px[pos] + dx[d], cy = py[pos] + dy[d];
    while (field[cy][cx] == -2 || done[cy][cx] == 1 || field[cy][cx] == 64) {
      cy += dy[d], cx += dx[d];
    }
    if (field[cy][cx] != -1) {
      done[cy][cx] = 1;
      ans += dfs(field[cy][cx], bit | (1 << field[cy][cx]));
      done[cy][cx] = 0;
    }
  }
  if (__builtin_popcount(bit) < 20) {
    return memo[pos][bit] = ans;
  } else {
    return ans;
  }
}

int main() {
  while (cin >> W >> H, W) {
    N = ans = 0;
    rep(i, 24) rep(j, 4) num[i][j] = -1;
    rep(i, 12) rep(j, 12) field[i][j] = -1;
    rep(i, H) rep(j, W) {
      int t;
      cin >> t;
      switch (t) {
      case 0:
        field[i + 1][j + 1] = -2;
        break;
      case 1:
        field[i + 1][j + 1] = N;
        px[N] = j + 1, py[N] = i + 1;
        N++;
        break;
      case 2:
        kx = j + 1, ky = i + 1;
        field[i + 1][j + 1] = 64;
        break;
      }
    }
    px[N] = kx, py[N] = ky;
    rep(i, 24) memo[i].clear();
    cout << dfs(N, 0) << endl;
  }
}