Problem p00471 (C++)

Buggy submission (status: Memory Limit Exceeded):
#include <cstdio>
#include <map>
#include <vector>
using namespace std;

typedef pair<int, int> P;

int m, n, pn, tmp;
int ans, upper;
map<int, int> dp[24];
// int dp[24][1<<18];
P pos[24];

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

int rec(int vis, int id) {
  if (dp[id].count(vis))
    return dp[id][vis];
  // if(__builtin_popcount(vis)>6 && dp[id][vis])return dp[id][vis];

  if (!vis && !id)
    return 1;

  int res = 0;
  int y = pos[id].first, x = pos[id].second;
  for (int k = 0; k < 4; k++) {
    int ty = y + dy[k], tx = x + dx[k];
    for (;;) {
      if (ty < 0 || tx < 0 || n <= ty || m <= tx)
        break;
      if (!vis && !g[ty][tx]) {
        res += 1;
        break;
      }
      if (0 < g[ty][tx]) {
        int tmp = g[ty][tx] - 1;
        if ((vis >> tmp) & 1) {
          res += rec(vis - (1 << tmp), g[ty][tx]);
          break;
        }
      }
      ty += dy[k];
      tx += dx[k];
    }
  }
  if (__builtin_popcount(vis) > 6)
    dp[id][vis] = res;
  return res;
}

int main() {
  while (scanf("%d%d", &m, &n), m || n) {
    pn = 1;
    for (int i = 0; i < n; i++) {
      for (int j = 0; j < m; j++) {
        scanf("%d", &tmp);
        if (tmp == 1) {
          g[i][j] = pn;
          pos[pn] = P(i, j);
          pn++;
        } else if (tmp == 2) {
          g[i][j] = 0;
          pos[0] = P(i, j);
        } else
          g[i][j] = -1;
      }
    }

    for (int i = 0; i < pn; i++)
      dp[i].clear();
    // for(int i=0;i<pn;i++)
    // for(int j=0;j<(1<<18);j++)dp[i][j] = 0;
    upper = (1 << (pn - 1));
    printf("%d\n", rec(upper - 1, 0));
  }
}

Fixed submission:
#include <cstdio>
#include <map>
#include <vector>
using namespace std;

typedef pair<int, int> P;

int m, n, pn, tmp;
int ans, upper;
map<int, int> dp[24];
// int dp[24][1<<18];
P pos[24];

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

int rec(int vis, int id) {
  if (dp[id].count(vis))
    return dp[id][vis];
  // if(__builtin_popcount(vis)>6 && dp[id][vis])return dp[id][vis];

  if (!vis && !id)
    return 1;

  int res = 0;
  int y = pos[id].first, x = pos[id].second;
  for (int k = 0; k < 4; k++) {
    int ty = y + dy[k], tx = x + dx[k];
    for (;;) {
      if (ty < 0 || tx < 0 || n <= ty || m <= tx)
        break;
      if (!vis && !g[ty][tx]) {
        res += 1;
        break;
      }
      if (0 < g[ty][tx]) {
        int tmp = g[ty][tx] - 1;
        if ((vis >> tmp) & 1) {
          res += rec(vis - (1 << tmp), g[ty][tx]);
          break;
        }
      }
      ty += dy[k];
      tx += dx[k];
    }
  }
  if (__builtin_popcount(vis) > 8)
    dp[id][vis] = res;
  return res;
}

int main() {
  while (scanf("%d%d", &m, &n), m || n) {
    pn = 1;
    for (int i = 0; i < n; i++) {
      for (int j = 0; j < m; j++) {
        scanf("%d", &tmp);
        if (tmp == 1) {
          g[i][j] = pn;
          pos[pn] = P(i, j);
          pn++;
        } else if (tmp == 2) {
          g[i][j] = 0;
          pos[0] = P(i, j);
        } else
          g[i][j] = -1;
      }
    }

    for (int i = 0; i < pn; i++)
      dp[i].clear();
    // for(int i=0;i<pn;i++)
    // for(int j=0;j<(1<<18);j++)dp[i][j] = 0;
    upper = (1 << (pn - 1));
    printf("%d\n", rec(upper - 1, 0));
  }
}