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

#include <algorithm>
#include <boost/functional/hash.hpp>
#include <cmath>
#include <cstdio>
#include <cstring>
#include <iostream>
#include <map>
#include <queue>
#include <stack>
#include <tr1/unordered_map>
#include <vector>
using namespace std;
using namespace tr1;
using namespace boost;

#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 mod 100000
#define DEB 0

/*
struct state{
  int s,c;
  state(int _s, int _c){
    s=_s; c=_c;
  }
};
struct state_eq{
  bool operator()(const state &a, const state &b)const{
    return a.s==b.s && a.c==b.c;
  }
};
struct ihash{
  size_t operator()(const state &a)const{
    size_t seed = 0;
    hash_combine(seed, a.s);
    return seed;
  }
};
*/

typedef unsigned short int usint;
int h, w;
char field[20][21];
int dp[20][20][17712];
int mask;
// unordered_map<state, bool, ihash, state_eq> hii;
unordered_map<int, usint> hii;

int solve(int c, int S) {
  if (c == w * h)
    return 1;
  int x = c % w;
  int y = c / w;
  int ret = 0;

  // unordered_map<state, int, ihash, state_eq>::iterator it;
  unordered_map<int, usint>::iterator it;
  it = hii.find(S);
  int idx;
  int sz = hii.size();
  if (it == hii.end()) {
    hii.insert(mp(S, sz));
    idx = sz;
  } else {
    idx = it->second;
  }

  if (dp[y][x][idx] != -1) {
    ret = dp[y][x][it->second];
  } else {
    if (field[y][x] == '?' || field[y][x] == 'J') {
      int next;
      if (S & 1) {
        next = ((S - 1) << 1) | 1;
      } else {
        next = (S << 1) | 1;
      }
      ret = (ret + solve(c + 1, next & mask)) % mod;
    }
    if (field[y][x] == '?' || field[y][x] == 'O') {
      ret = (ret + solve(c + 1, (S << 1) & mask)) % mod;
    }
    if (field[y][x] == '?' || field[y][x] == 'I') {
      if (x == w - 1 || !((1 << (w - 1)) & S)) {
        int next;
        if (S & 1) {
          next = (S - 1) << 1;
        } else {
          next = S << 1;
        }
        ret = (ret + solve(c + 1, next & mask)) % mod;
      }
    }
    dp[y][x][idx] = ret;
  }

  return ret;
}

int main() {

  while (~scanf("%d%d", &h, &w)) {
    hii.clear();
    memset(dp, -1, sizeof(dp));
    int all = 1;
    rep(i, h) scanf("%s", field[i]);
    rep(i, h) rep(j, w) if (field[i][j] == '?') { all = (all * 3) % mod; }
    mask = (1 << w) - 1;

    int wr = solve(0, 0);
    printf("%d\\n", (all - wr + mod) % mod);

#if DEB
    cout << hii.size() << endl;
#endif
  }
  return 0;
}

Error: MLE

Fixed submission:

#include <algorithm>
#include <boost/functional/hash.hpp>
#include <cmath>
#include <cstdio>
#include <cstring>
#include <iostream>
#include <map>
#include <queue>
#include <stack>
#include <tr1/unordered_map>
#include <vector>
using namespace std;
using namespace tr1;
using namespace boost;

#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 mod 100000
#define DEB 0

/*
struct state{
  int s,c;
  state(int _s, int _c){
    s=_s; c=_c;
  }
};
struct state_eq{
  bool operator()(const state &a, const state &b)const{
    return a.s==b.s && a.c==b.c;
  }
};
struct ihash{
  size_t operator()(const state &a)const{
    size_t seed = 0;
    hash_combine(seed, a.s);
    return seed;
  }
};
*/

int h, w;
char field[32][32];
int dp[22][22][17712];
// unordered_map<state, bool, ihash, state_eq> hii;
unordered_map<int, int> hii;

int solve(int c, int S) {
  if (c == w * h)
    return 1;
  int x = c % w;
  int y = c / w;
  int mask = (1 << w) - 1;
  int ret = 0;

  // unordered_map<state, int, ihash, state_eq>::iterator it;
  unordered_map<int, int>::iterator it;
  it = hii.find(S);
  int idx;
  int sz = hii.size();
  if (it == hii.end()) {
    hii.insert(mp(S, sz));
    idx = sz;
  } else {
    idx = it->second;
  }

  if (dp[y][x][idx] != -1) {
    ret = dp[y][x][it->second];
  } else {
    if (field[y][x] == '?' || field[y][x] == 'J') {
      int next;
      if (S & 1) {
        next = ((S - 1) << 1) | 1;
      } else {
        next = (S << 1) | 1;
      }
      ret = (ret + solve(c + 1, next & mask)) % mod;
    }
    if (field[y][x] == '?' || field[y][x] == 'O') {
      ret = (ret + solve(c + 1, (S << 1) & mask)) % mod;
    }
    if (field[y][x] == '?' || field[y][x] == 'I') {
      if (x == w - 1 || !((1 << (w - 1)) & S)) {
        int next;
        if (S & 1) {
          next = (S - 1) << 1;
        } else {
          next = S << 1;
        }
        ret = (ret + solve(c + 1, next & mask)) % mod;
      }
    }
    dp[y][x][idx] = ret;
  }

  return ret;
}

int main() {

  while (~scanf("%d%d", &h, &w)) {
    hii.clear();
    memset(dp, -1, sizeof(dp));
    int all = 1;
    rep(i, h) scanf("%s", field[i]);
    rep(i, h) rep(j, w) if (field[i][j] == '?') { all = (all * 3) % mod; }

#if DEB
    rep(i, h) { puts(field[i]); }
#endif
    int wr = solve(0, 0);
    printf("%d\\n", (all - wr + mod) % mod);
  }
  return 0;
}