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

#include <cstdio>
#include <cstring>
#include <iostream>
#include <map>
#include <vector>
#define fi first
#define sec second
using namespace std;
typedef pair<int, int> P;

int n, m;
int S;
int ans;
int cell[10][10];
int dy[4] = {1, 0, -1, 0}, dx[4] = {0, 1, 0, -1};
int used;
map<P, int> dp;
vector<int> e[30][4]; // 0 down 1 right 2 up 3 left
vector<P> num;

int A(int s, int cnt) {
  /*
  if(dp[P(used,s)] > 0){
          return dp[P(used,s)];
  }
  */
  int ret = 0;
  cnt--;
  if (cnt == 0) {
    for (int i = 0; i < 4; i++) {
      for (int j = 0; j < e[s][i].size(); j++) {
        if (e[s][i][j] == S)
          ret++;
      }
    }
    // dp[P(used,s)] = ret;
    return ret;
  }
  if (s != S)
    used += 1 << s;
  for (int i = 0; i < 4; i++) {
    for (int j = 0; j < e[s][i].size(); j++) {
      if (used >> e[s][i][j] & 1)
        continue;
      if (e[s][i][j] == S)
        continue;
      ret += A(e[s][i][j], cnt);
      break;
    }
  }
  if (s != S)
    used -= 1 << s;
  // dp[P(used,s)] = ret;
  return ret;
}

void solve() {
  ans = 0;
  num.clear();
  used = 0;
  dp.clear();
  for (int i = 0; i < 30; i++) {
    for (int j = 0; j < 4; j++) {
      e[i][j].clear();
    }
  }
  for (int i = 0; i < n; i++) {
    for (int j = 0; j < m; j++) {
      scanf("%d", &cell[i][j]);
      if (cell[i][j] != 0) {
        if (cell[i][j] == 2)
          S = num.size();
        num.push_back(P(i, j));
      }
    }
  }
  for (int i = 0; i < n; i++) {
    for (int j = 0; j < m; j++) {
      if (cell[i][j] == 0)
        continue;
      int tmp;
      for (int k = 0; k < num.size(); k++) {
        if (num[k].fi == i && num[k].sec == j) {
          tmp = k;
          break;
        }
      }
      for (int k = 0; k < 4; k++) {
        int y = i, x = j;
        while (true) {
          y += dy[k];
          x += dx[k];
          if (0 > y || y >= n || 0 > x || x >= m)
            break;
          if (cell[y][x] != 0) {
            for (int l = 0; l < num.size(); l++) {
              if (num[l].fi == y && num[l].sec == x) {
                e[tmp][k].push_back(l);
                break;
              }
            }
          }
        }
      }
    }
  }
  ans = A(S, num.size());
  printf("%d\\n", ans);
}

int main() {
  while (scanf("%d%d", &m, &n), n || m)
    solve();
}

Error: MLE

Fixed submission:

#include <cstdio>
#include <cstring>
#include <iostream>
#include <map>
#include <vector>
#define fi first
#define sec second
using namespace std;
typedef pair<int, int> P;

int n, m;
int S;
int ans;
int cell[10][10];
int dy[4] = {1, 0, -1, 0}, dx[4] = {0, 1, 0, -1};
int used;
map<P, int> dp;
vector<int> e[30][4]; // 0 down 1 right 2 up 3 left
vector<P> num;

int A(int s, int cnt) {
  if (dp[P(used, s)] > 0) {
    return dp[P(used, s)];
  }
  int ret = 0;
  cnt--;
  if (cnt == 0) {
    for (int i = 0; i < 4; i++) {
      if (e[s][i].size() != 0 && e[s][i][0] == S) {
        ret++;
      }
    }
    dp[P(used, s)] = ret;
    return ret;
  }
  if (s != S)
    used += 1 << s;
  for (int i = 0; i < 4; i++) {
    for (int j = 0; j < e[s][i].size(); j++) {
      if (used >> e[s][i][j] & 1)
        break;
      if (e[s][i][j] == S)
        continue;
      ret += A(e[s][i][j], cnt);
    }
  }
  if (s != S)
    used -= 1 << s;
  dp[P(used, s)] = ret;
  return ret;
}

void solve() {
  ans = 0;
  num.clear();
  used = 0;
  dp.clear();
  for (int i = 0; i < 30; i++) {
    for (int j = 0; j < 4; j++) {
      e[i][j].clear();
    }
  }
  for (int i = 0; i < n; i++) {
    for (int j = 0; j < m; j++) {
      scanf("%d", &cell[i][j]);
      if (cell[i][j] != 0) {
        if (cell[i][j] == 2)
          S = num.size();
        num.push_back(P(i, j));
      }
    }
  }
  for (int i = 0; i < n; i++) {
    for (int j = 0; j < m; j++) {
      if (cell[i][j] == 0)
        continue;
      int tmp;
      for (int k = 0; k < num.size(); k++) {
        if (num[k].fi == i && num[k].sec == j) {
          tmp = k;
          break;
        }
      }
      for (int k = 0; k < 4; k++) {
        int y = i, x = j;
        while (true) {
          y += dy[k];
          x += dx[k];
          if (0 > y || y >= n || 0 > x || x >= m)
            break;
          if (cell[y][x] != 0) {
            for (int l = 0; l < num.size(); l++) {
              if (num[l].fi == y && num[l].sec == x) {
                e[tmp][k].push_back(l);
                break;
              }
            }
          }
        }
      }
    }
  }
  ans = A(S, num.size());
  printf("%d\\n", ans);
}

int main() {
  while (scanf("%d%d", &m, &n), n || m)
    solve();
}