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

#include <bits/stdc++.h>
#define rep(i, n) for (int i = 0; i < (int)(n); i++)
#define rep1(i, n) for (int i = 1; i <= (int)(n); i++)
#define all(c) c.begin(), c.end()
#define pb push_back
#define fs first
#define sc second
#define show(x) cout << #x << " = " << x << endl
#define chmin(x, y) x = min(x, y)
#define chmax(x, y) x = max(x, y)
using namespace std;
typedef vector<int> vi;
typedef pair<int, int> P;
typedef pair<vi, int> Vii;
typedef long long ull;
ull B = 1e7 + 7;
int dx[9] = {-1, -1, -1, 0, 0, 0, 1, 1, 1},
    dy[9] = {-1, 0, 1, -1, 0, 1, -1, 0, 1};
int H, W, I;
string s[15];
int id[15][15];
vector<int> ns;
vi nei[15][15];
vi htons[15];
map<int, int> mp;
int myhash(int h, int w) {
  ull s = h * W + w;
  rep(i, I) s = s * B + ns[i];
  return (int)s;
}
void init(int H, int W) {
  I = 0;
  rep(i, H) rep(j, W) id[i][j] = -1;
  ns.clear();
  rep(i, H) rep(j, W) nei[i][j].clear();
  rep(i, H) htons[i].clear();
  mp.clear();
}
bool is(int x, int y) { return 0 <= x and x < H and 0 <= y and y < W; }
bool put(int h, int w) {
  for (int v : nei[h][w]) {
    if (ns[v] == 0)
      return false;
  }
  for (int v : nei[h][w])
    ns[v]--;
  return true;
}
void rmv(int h, int w) {
  for (int v : nei[h][w])
    ns[v]++;
}
bool linecheck(int h) {
  if (h < 0)
    return 1;
  for (int n : htons[h])
    if (ns[n] != 0)
      return 0;
  return 1;
}
bool ok() {
  for (int n : ns)
    if (n != 0)
      return false;
  return true;
}
int dfs(int h, int w) {
  if (w == W) {
    if (!linecheck(h - 1))
      return 114514;
    return dfs(h + 1, 0);
  }
  if (h == H) {
    if (ok())
      return 0;
    else
      return 114514;
  }
  if (s[h][w] == '.' || nei[h][w].empty())
    return dfs(h, w + 1);
  if (mp.count(myhash(h, w)))
    return mp[myhash(h, w)];
  int ret = dfs(h, w + 1);
  if (put(h, w)) {
    chmin(ret, dfs(h, w + 1) + 1);
    rmv(h, w);
  }
  mp[myhash(h, w)] = ret;
  return ret;
}
int main() {
  while (true) {
    cin >> H >> W;
    if (H == 0)
      break;
    rep(i, H) cin >> s[i];
    if (H < W) {
      string st[15];
      rep(i, H) st[i] = s[i];
      rep(i, W) s[i].resize(H);
      rep(i, W) rep(j, H) s[i][j] = st[j][i];
      swap(H, W);
    }
    init(H, W);
    rep(i, H) rep(j, W) if (isdigit(s[i][j])) {
      id[i][j] = I++;
      ns.pb(s[i][j] - '0');
      htons[i].pb(id[i][j]);
    }
    rep(i, H) rep(j, W) {
      rep(d, 9) {
        int ni = i + dx[d], nj = j + dy[d];
        if (is(ni, nj) && isdigit(s[ni][nj]))
          nei[i][j].pb(id[ni][nj]);
      }
    }
    cout << dfs(0, 0) << endl;
  }
}

Error: MLE

Fixed submission:

#include <bits/stdc++.h>
#define rep(i, n) for (int i = 0; i < (int)(n); i++)
#define rep1(i, n) for (int i = 1; i <= (int)(n); i++)
#define all(c) c.begin(), c.end()
#define pb push_back
#define fs first
#define sc second
#define show(x) cout << #x << " = " << x << endl
#define chmin(x, y) x = min(x, y)
#define chmax(x, y) x = max(x, y)
using namespace std;
typedef vector<int> vi;
typedef pair<int, int> P;
typedef pair<vi, int> Vii;
typedef long long ull;
ull B = 1e7 + 7;
int dx[9] = {-1, -1, -1, 0, 0, 0, 1, 1, 1},
    dy[9] = {-1, 0, 1, -1, 0, 1, -1, 0, 1};
int H, W, I;
string s[15];
int id[15][15];
vector<int> ns;
vi nei[15][15];
vi htons[15];
map<int, int> mp;
int myhash(int h, int w) {
  ull s = h * W + w;
  rep(i, I) s = s * B + ns[i];
  return (int)s;
}
void init(int H, int W) {
  I = 0;
  rep(i, H) rep(j, W) id[i][j] = -1;
  ns.clear();
  rep(i, H) rep(j, W) nei[i][j].clear();
  rep(i, H) htons[i].clear();
  mp.clear();
}
bool is(int x, int y) { return 0 <= x and x < H and 0 <= y and y < W; }
bool put(int h, int w) {
  for (int v : nei[h][w]) {
    if (ns[v] == 0)
      return false;
  }
  for (int v : nei[h][w])
    ns[v]--;
  return true;
}
void rmv(int h, int w) {
  for (int v : nei[h][w])
    ns[v]++;
}
bool linecheck(int h) {
  if (h < 0)
    return 1;
  for (int n : htons[h])
    if (ns[n] != 0)
      return 0;
  return 1;
}
bool ok() {
  for (int n : ns)
    if (n != 0)
      return false;
  return true;
}
int dfs(int h, int w) {
  if (w == W) {
    if (!linecheck(h - 1))
      return 114514;
    return dfs(h + 1, 0);
  }
  if (h == H) {
    if (ok())
      return 0;
    else
      return 114514;
  }
  if (s[h][w] == '.' || nei[h][w].empty())
    return dfs(h, w + 1);
  if (mp.count(myhash(h, w)))
    return mp[myhash(h, w)];
  int ret = dfs(h, w + 1);
  if (put(h, w)) {
    chmin(ret, dfs(h, w + 1) + 1);
    rmv(h, w);
  }
  mp[myhash(h, w)] = ret;
  return ret;
}
int main() {
  while (true) {
    cin >> H >> W;
    if (H == 0)
      break;
    init(H, W);
    rep(i, H) cin >> s[i];
    rep(i, H) rep(j, W) if (isdigit(s[i][j])) {
      id[i][j] = I++;
      ns.pb(s[i][j] - '0');
      htons[i].pb(id[i][j]);
    }
    rep(i, H) rep(j, W) {
      rep(d, 9) {
        int ni = i + dx[d], nj = j + dy[d];
        if (is(ni, nj) && isdigit(s[ni][nj]))
          nei[i][j].pb(id[ni][nj]);
      }
    }
    cout << dfs(0, 0) << endl;
  }
}