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

#include <algorithm>
#include <cassert>
#include <cmath>
#include <cstdio>
#include <cstdlib>
#include <functional>
#include <iostream>
#include <map>
#include <queue>
#include <set>
#include <stack>
#include <string>
#include <vector>

typedef long long ll;
using namespace std;

#define mod 1000000007
#define INF 1000000000
#define LLINF 2000000000000000000LL

int m, n;
int mm[10][10] = {0};
int ch_y, ch_x;
int mo4[] = {0, 1, 0, -1, 0};
int max_v = 1;

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

// int memo[10][10][1<<23]={0};

int dfs(int y, int x, int v) {
  int ret = 0;
  // pair<pair<int,int>,int> p = {{y,x},v};
  // if(memo[p]) return memo[p];

  // fprintf(stderr,"(%2d,%2d) : %d\\n",x,y,v);

  for (int i = 0; i < 4; i++) {
    int tox = x, toy = y;

    while (1) {
      tox += mo4[i];
      toy += mo4[i + 1];

      if (tox < 0 || m <= tox || toy < 0 || n <= toy)
        break;

      if (mm[toy][tox] == 0)
        continue;

      if (mm[toy][tox] == -1) {
        if (max_v == v) {
          return 1;
        } else {
          continue;
        }
      }

      if (mm[toy][tox] & v)
        continue;

      ret += dfs(toy, tox, v | mm[toy][tox]);
      break;
    }
  }

  // fprintf(stderr,"memo[%2d][%2d][%2d] = %lld\\n",x,y,v,ret%mod);
  /*
  if(__builtin_popcount(ret) <= 18)
      memo[p] = ret;
  */
  return ret;
}

void calc(int m, int n) {

  // memset(memo,0,sizeof(memo));

  // memo.clear();

  max_v = 1;

  for (int i = 0; i < n; i++) {
    for (int j = 0; j < m; j++) {
      scanf("%d", &mm[i][j]);

      if (mm[i][j] == 1) {
        mm[i][j] = max_v;
        max_v *= 2;
      } else if (mm[i][j] == 2) {
        mm[i][j] = -1;
        ch_y = i;
        ch_x = j;
      }
    }
  }

  max_v--;

  printf("%d\\n", dfs(ch_y, ch_x, 0));

  return;
}

int main() {
  while (1) {
    scanf("%d%d", &m, &n);
    if (m == 0)
      break;
    calc(m, n);
  }
}

Error: MLE

Fixed submission:

#include <algorithm>
#include <cassert>
#include <cmath>
#include <cstdio>
#include <cstdlib>
#include <functional>
#include <iostream>
#include <map>
#include <queue>
#include <set>
#include <stack>
#include <string>
#include <vector>

typedef long long ll;
using namespace std;

#define mod 1000000007
#define INF 1000000000
#define LLINF 2000000000000000000LL

int m, n;
int mm[10][10] = {0};
int ch_y, ch_x;
int mo4[] = {0, 1, 0, -1, 0};
int max_v = 1;

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

// int memo[10][10][1<<23]={0};

int dfs(int y, int x, int v) {
  int ret = 0;
  pair<pair<int, int>, int> p = {{y, x}, v};
  if (memo[p])
    return memo[p];

  // fprintf(stderr,"(%2d,%2d) : %d\\n",x,y,v);

  for (int i = 0; i < 4; i++) {
    int tox = x, toy = y;

    while (1) {
      tox += mo4[i];
      toy += mo4[i + 1];

      if (tox < 0 || m <= tox || toy < 0 || n <= toy)
        break;

      if (mm[toy][tox] == 0)
        continue;

      if (mm[toy][tox] == -1) {
        if (max_v == v) {
          return 1;
        } else {
          continue;
        }
      }

      if (mm[toy][tox] & v)
        continue;

      ret += dfs(toy, tox, v | mm[toy][tox]);
      break;
    }
  }

  // fprintf(stderr,"memo[%2d][%2d][%2d] = %lld\\n",x,y,v,ret%mod);

  if (__builtin_popcount(ret) <= 18)
    memo[p] = ret;

  return ret;
}

void calc(int m, int n) {

  // memset(memo,0,sizeof(memo));

  memo.clear();

  max_v = 1;

  for (int i = 0; i < n; i++) {
    for (int j = 0; j < m; j++) {
      scanf("%d", &mm[i][j]);

      if (mm[i][j] == 1) {
        mm[i][j] = max_v;
        max_v *= 2;
      } else if (mm[i][j] == 2) {
        mm[i][j] = -1;
        ch_y = i;
        ch_x = j;
      }
    }
  }

  max_v--;

  printf("%d\\n", dfs(ch_y, ch_x, 0));

  return;
}

int main() {
  while (1) {
    scanf("%d%d", &m, &n);
    if (m == 0)
      break;
    calc(m, n);
  }
}