Problem p00900 (C++)

Buggy submission (status: Memory Limit Exceeded):
#include <bits/stdc++.h>
#define int long long
using namespace std;

string s[15];

int h, w;
int t[15][15], A[15][15];

void init() {

  memset(t, 0, sizeof(t));
  memset(A, 0, sizeof(A));

  for (int i = 0; i < h; i++) {

    for (int j = 0; j < w; j++) {

      if (s[i][j] != '.' && s[i][j] != '*') {

        if (s[i][j] == '0')
          continue;

        t[i][j] = 1;
        A[i][j] = s[i][j] - '0';
      }
    }
  }
}

bool check() {

  for (int i = 0; i < h; i++) {
    for (int j = 0; j < w; j++) {
      if (A[i][j] != 0)
        return false;
    }
  }

  return true;
}

int update(int y, int x) {

  int flag = 1;

  for (int i = -1; i <= 1; i++) {

    for (int j = -1; j <= 1; j++) {

      int ny = y + i, nx = x + j;

      if (ny < 0 || nx < 0 || h <= ny || w <= nx)
        continue;

      if (t[ny][nx] && A[ny][nx] == 0)
        flag = 0;
    }
  }

  if (flag == 1) {

    for (int i = -1; i <= 1; i++) {

      for (int j = -1; j <= 1; j++) {

        int ny = y + i, nx = x + j;

        if (ny < 0 || nx < 0 || h <= ny || w <= nx)
          continue;

        if (t[ny][nx])
          A[ny][nx]--;
      }
    }
  }

  return flag;
}

void add(int y, int x) {

  for (int i = -1; i <= 1; i++) {

    for (int j = -1; j <= 1; j++) {

      int ny = y + i, nx = x + j;

      if (ny < 0 || nx < 0 || h <= ny || w <= nx)
        continue;

      if (t[ny][nx])
        A[ny][nx]++;
    }
  }
}

const int INF = 1e8;

typedef unsigned long long ull;

ull Hash() {

  ull res = 0, base = 1777771;

  for (int i = 0; i < h; i++) {
    for (int j = 0; j < w; j++) {
      if (t[i][j])
        res = res * base + A[i][j] + 1;
    }
  }

  return res;
}

bool End(int y, int x) {

  for (int i = 0; i < y; i++) {

    for (int j = 0; j < w; j++) {

      if (A[i][j] && abs(y - i) == 2)
        return true;
    }
  }

  return false;
}

map<ull, int> memo[15][15];

int dfs(int y, int x) {

  if (y == h) {
    if (check() == false)
      return INF;
    return 0;
  }

  if (End(y, x) == true)
    return INF;

  if (memo[y][x].count(Hash()))
    return memo[y][x][Hash()];

  int ny = y, nx = x + 1;

  if (nx == w)
    ny++, nx = 0;

  int res = INF;

  res = min(res, dfs(ny, nx));

  if (t[y][x] == 1 || s[y][x] == '*') {

    int r = update(y, x);

    res = min(res, dfs(ny, nx) + r);

    if (r == 1)
      add(y, x);
  }

  return memo[y][x][Hash()] = res;
}

signed main() {

  while (1) {

    cin >> h >> w;
    if (!h && !w)
      break;

    for (int i = 0; i < h; i++)
      cin >> s[i];

    init();

    for (int i = 0; i < h; i++)
      for (int j = 0; j < w; j++)
        memo[i][j].clear();

    cout << dfs(0, 0) << endl;
  }

  return 0;
}


Fixed submission:
#include <bits/stdc++.h>
#define int long long
using namespace std;

string s[15];

int h, w;
int t[15][15], A[15][15];

void init() {

  memset(t, 0, sizeof(t));
  memset(A, 0, sizeof(A));

  for (int i = 0; i < h; i++) {

    for (int j = 0; j < w; j++) {

      if (s[i][j] != '.' && s[i][j] != '*') {

        if (s[i][j] == '0')
          continue;

        t[i][j] = 1;
        A[i][j] = s[i][j] - '0';
      }
    }
  }
}

bool check() {

  for (int i = 0; i < h; i++) {
    for (int j = 0; j < w; j++) {
      if (A[i][j] != 0)
        return false;
    }
  }

  return true;
}

int update(int y, int x) {

  int flag = 1;

  for (int i = -1; i <= 1; i++) {

    for (int j = -1; j <= 1; j++) {

      int ny = y + i, nx = x + j;

      if (ny < 0 || nx < 0 || h <= ny || w <= nx)
        continue;

      if (t[ny][nx] && A[ny][nx] == 0)
        flag = 0;
    }
  }

  if (flag == 1) {

    for (int i = -1; i <= 1; i++) {

      for (int j = -1; j <= 1; j++) {

        int ny = y + i, nx = x + j;

        if (ny < 0 || nx < 0 || h <= ny || w <= nx)
          continue;

        if (t[ny][nx])
          A[ny][nx]--;
      }
    }
  }

  return flag;
}

void add(int y, int x) {

  for (int i = -1; i <= 1; i++) {

    for (int j = -1; j <= 1; j++) {

      int ny = y + i, nx = x + j;

      if (ny < 0 || nx < 0 || h <= ny || w <= nx)
        continue;

      if (t[ny][nx])
        A[ny][nx]++;
    }
  }
}

const int INF = 1e8;

typedef unsigned long long ull;

ull Hash() {

  ull res = 0, base = 1777771;

  for (int i = 0; i < h; i++) {
    for (int j = 0; j < w; j++) {
      if (t[i][j])
        res = res * base + A[i][j] + 1;
    }
  }

  return res;
}

bool End(int y, int x) {

  for (int i = 0; i < y; i++) {

    for (int j = 0; j < w; j++) {

      if (A[i][j]) {
        if (y - i >= 2)
          return true;
        if (y - i == 1 && x - j >= 2)
          return true;
      }
    }
  }

  return false;
}

map<ull, int> memo[15][15];

int dfs(int y, int x) {

  if (y == h) {
    if (check() == false)
      return INF;
    return 0;
  }

  if (End(y, x) == true)
    return INF;

  if (memo[y][x].count(Hash()))
    return memo[y][x][Hash()];

  int ny = y, nx = x + 1;

  if (nx == w)
    ny++, nx = 0;

  int res = INF;

  res = min(res, dfs(ny, nx));

  if (t[y][x] == 1 || s[y][x] == '*') {

    int r = update(y, x);

    res = min(res, dfs(ny, nx) + r);

    if (r == 1)
      add(y, x);
  }

  return memo[y][x][Hash()] = res;
}

signed main() {

  while (1) {

    cin >> h >> w;
    if (!h && !w)
      break;

    for (int i = 0; i < h; i++)
      cin >> s[i];

    init();

    for (int i = 0; i < h; i++)
      for (int j = 0; j < w; j++)
        memo[i][j].clear();

    cout << dfs(0, 0) << endl;
  }

  return 0;
}