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

#include <algorithm>
#include <cmath>
#include <cstdio>
#include <cstring>
#include <iostream>
#include <map>
#include <stack>
#include <vector>
using namespace std;

#define REP(i, a, n) for (int i = (a); i < (int)(n); i++)
#define rep(i, n) REP(i, 0, n)
#define mp make_pair
#define pb push_back
#define all(x) (x).begin(), (x).end()
#define EPS 1e-8
#define DEB 0

const int dx[] = {0, 1, 0, -1};
const int dy[] = {-1, 0, 1, 0};
int w, h, sx, sy, home, last;
int field[16][16];
int num[16][16];

#if DEB
stack<int> st;
#endif

class state {
public:
  char x, y;
  int s;
  state(char _x, char _y, int _s) {
    x = _x;
    y = _y;
    s = _s;
  }

  bool operator<(const state &a) const {
    if (x == a.x) {
      if (y == a.y)
        return s < a.s;
      else
        return y < a.y;
    } else {
      return x < a.x;
    }
  }
};

map<state, int> msi;

bool ischeck(int s) { return (((last & s)) == last); }
bool inside(int x, int y) { return (x < 0 || y < 0 || x >= w || y >= h); }

int dfs(int x, int y, int s) {
  if ((1 << home) - 1 ==
      s) { //  ÆÍ³ïÉßêé©Ç¤©
    rep(k, 4) {
      for (int i = 1; i < 20; i++) {
        int tx = x + dx[k] * i;
        int ty = y + dy[k] * i;
        // if( inside(tx,ty) || field[ty][tx]==1 )break;
        if (inside(tx, ty))
          break;

        if (field[ty][tx] == 2) {
#if DEB
          printf("goal , (%d,%d)  s:%d\\n", x, y, s);
          stack<int> tmp = st;
          while (!tmp.empty()) {
            printf("%d,", tmp.top());
            tmp.pop();
          }
          puts("\\n");
#endif
          return 1;
        }
      }
    }
    return 0;
  }
  if (msi.count(state(x, y, s))) { // ùÉÊÁ½ê
    return msi[state(x, y, s)];
  }
  if (ischeck(s)) {
    return 0;
  }

  int ret = 0;
  rep(k, 4) {
    for (int i = 1; i < 20; i++) {
      int tx = x + dx[k] * i;
      int ty = y + dy[k] * i;
      if (inside(tx, ty))
        break;
      if (field[ty][tx] == 1) {
        // if( s&(1<<num[ty][tx]) ) break;
        field[ty][tx] = 0;
#if DEB
        st.push(num[ty][tx]);
#endif
        ret += dfs(tx, ty, s | (1 << num[ty][tx]));
#if DEB
        st.pop();
#endif
        field[ty][tx] = 1;
        break;
      }
    }
  }
  msi[state(x, y, s)] = ret;
  return ret;
}

int main() {

  while (scanf("%d%d", &w, &h), w | h) {
    msi.clear();
    memset(num, -1, sizeof(num));
    home = last = 0;
    rep(i, h) {
      rep(j, w) {
        scanf("%d", &field[i][j]);
        if (field[i][j] == 2) {
          sx = j;
          sy = i;
        }
        if (field[i][j] == 1) {
          num[i][j] = home;
          home++;
        }
      }
    }

    // last homes
    rep(k, 4) {
      for (int i = 1; i < 20; i++) {
        int tx = sx + dx[k] * i;
        int ty = sy + dy[k] * i;
        if (inside(tx, ty))
          break;
        if (field[ty][tx] == 1) {
          last |= (1 << num[ty][tx]);
        }
      }
    }
#if DEB
    printf("home:%d  sx,sy = %d,%d\\n", home, sx, sy);
    printf("last:%d\\n", last);
    rep(i, h) {
      rep(j, w) { printf("%2d ", num[i][j]); }
      puts("");
    }
#endif
    dfs(sx, sy, 0);
    printf("%d\\n", msi[state(sx, sy, 0)]);
  }

  return 0;
}

Error: MLE

Fixed submission:

#include <algorithm>
#include <cmath>
#include <cstdio>
#include <cstring>
#include <iostream>
#include <map>
#include <stack>
#include <vector>
using namespace std;

#define REP(i, a, n) for (int i = (a); i < (int)(n); i++)
#define rep(i, n) REP(i, 0, n)
#define mp make_pair
#define pb push_back
#define all(x) (x).begin(), (x).end()
#define EPS 1e-8
#define DEB 0

const int dx[] = {0, 1, 0, -1};
const int dy[] = {-1, 0, 1, 0};
int w, h, sx, sy, home, last;
int field[16][16];
int num[16][16];

#if DEB
stack<int> st;
#endif

class state {
public:
  int x, y, s;
  state(int _x, int _y, int _s) {
    x = _x;
    y = _y;
    s = _s;
  }

  bool operator<(const state &a) const {
    if (x == a.x) {
      if (y == a.y)
        return s < a.s;
      else
        return y < a.y;
    } else {
      return x < a.x;
    }
  }
};

map<state, int> msi;

bool ischeck(int s) { return (((last & s)) == last); }
bool inside(int x, int y) { return (x < 0 || y < 0 || x >= w || y >= h); }

int dfs(int x, int y, int s) {
  if ((1 << home) - 1 ==
      s) { //  ÆÍ³ïÉßêé©Ç¤©
    rep(k, 4) {
      for (int i = 1; i < 20; i++) {
        int tx = x + dx[k] * i;
        int ty = y + dy[k] * i;
        // if( inside(tx,ty) || field[ty][tx]==1 )break;
        if (inside(tx, ty))
          break;

        if (field[ty][tx] == 2) {
#if DEB
          printf("goal , (%d,%d)  s:%d\\n", x, y, s);
          stack<int> tmp = st;
          while (!tmp.empty()) {
            printf("%d,", tmp.top());
            tmp.pop();
          }
          puts("\\n");
#endif
          return 1;
        }
      }
    }
    return 0;
  }
  if (msi.count(state(x, y, s))) { // ùÉÊÁ½ê
    return msi[state(x, y, s)];
  }
  if (ischeck(s)) {
    return 0;
  }

  int ret = 0;
  rep(k, 4) {
    for (int i = 1; i < 20; i++) {
      int tx = x + dx[k] * i;
      int ty = y + dy[k] * i;
      if (inside(tx, ty))
        break;
      if (field[ty][tx] == 1) {
        // if( s&(1<<num[ty][tx]) ) break;
        field[ty][tx] = 0;
#if DEB
        st.push(num[ty][tx]);
#endif
        ret += dfs(tx, ty, s | (1 << num[ty][tx]));
#if DEB
        st.pop();
#endif
        field[ty][tx] = 1;
        break;
      }
    }
  }
  msi[state(x, y, s)] = ret;
  return ret;
}

int main() {

  while (scanf("%d%d", &w, &h), w | h) {
    msi.clear();
    memset(num, -1, sizeof(num));
    home = last = 0;
    rep(i, h) {
      rep(j, w) {
        scanf("%d", &field[i][j]);
        if (field[i][j] == 2) {
          sx = j;
          sy = i;
        }
        if (field[i][j] == 1) {
          num[i][j] = home;
          home++;
        }
      }
    }

    // last homes
    rep(k, 4) {
      for (int i = 1; i < 20; i++) {
        int tx = sx + dx[k] * i;
        int ty = sy + dy[k] * i;
        if (inside(tx, ty))
          break;
        if (field[ty][tx] == 1) {
          last |= (1 << num[ty][tx]);
        }
      }
    }
#if DEB
    printf("home:%d  sx,sy = %d,%d\\n", home, sx, sy);
    printf("last:%d\\n", last);
    rep(i, h) {
      rep(j, w) { printf("%2d ", num[i][j]); }
      puts("");
    }
#endif
    dfs(sx, sy, 0);
    printf("%d\\n", msi[state(sx, sy, 0)]);
  }

  return 0;
}