Problem p04009 (C++)

Buggy submission (status: Memory Limit Exceeded):
#include <bits/stdc++.h>
using namespace std;
template <class T> int size(const T &x) { return x.size(); }
#define rep(i, a, b) for (__typeof(a) i = (a); i < (b); ++i)
#define iter(it, c)                                                            \
  for (__typeof((c).begin()) it = (c).begin(); it != (c).end(); ++it)
typedef pair<int, int> ii;
typedef vector<int> vi;
typedef vector<ii> vii;
typedef long long ll;
const int INF = 2147483647;

char board[110][110];
int cnt[110][110];
int mem[100][100][100][100]; // TODO: short?
int n, m;

#define Q(a, b, c, d)                                                          \
  (cnt[b + 1][d + 1] - cnt[b + 1][c] - cnt[a][d + 1] + cnt[a][c])

int dp(int x0, int x1, int y0, int y1, int ax0, int ax1, int ay0, int ay1) {

  if (mem[x0][x1][y0][y1] != -1) {
    return mem[x0][x1][y0][y1];
  }

  int res = 0;
  if (x0 > 0) {
    int add = 0;
    int qx0 = max(x0 - 1, ax0), qx1 = min(x0 - 1, ax1), qy0 = max(y0, ay0),
        qy1 = min(y1, ay1);
    if (qx0 <= qx1 && qy0 <= qy1)
      add = Q(qx0, qx1, qy0, qy1);
    res = max(res, add + dp(x0 - 1, x1, y0, y1, ax0, ax1 - 1, ay0, ay1));
  }
  if (x1 < n - 1) {
    int add = 0;
    int qx0 = max(x1 + 1, ax0), qx1 = min(x1 + 1, ax1), qy0 = max(y0, ay0),
        qy1 = min(y1, ay1);
    if (qx0 <= qx1 && qy0 <= qy1)
      add = Q(qx0, qx1, qy0, qy1);
    res = max(res, add + dp(x0, x1 + 1, y0, y1, ax0 + 1, ax1, ay0, ay1));
  }
  if (y0 > 0) {
    int add = 0;
    int qx0 = max(x0, ax0), qx1 = min(x1, ax1), qy0 = max(y0 - 1, ay0),
        qy1 = min(y0 - 1, ay1);
    if (qx0 <= qx1 && qy0 <= qy1)
      add = Q(qx0, qx1, qy0, qy1);
    res = max(res, add + dp(x0, x1, y0 - 1, y1, ax0, ax1, ay0, ay1 - 1));
  }
  if (y1 < m - 1) {
    int add = 0;
    int qx0 = max(x0, ax0), qx1 = min(x1, ax1), qy0 = max(y1 + 1, ay0),
        qy1 = min(y1 + 1, ay1);
    if (qx0 <= qx1 && qy0 <= qy1)
      add = Q(qx0, qx1, qy0, qy1);
    res = max(res, add + dp(x0, x1, y0, y1 + 1, ax0, ax1, ay0 + 1, ay1));
  }

  // int qx0 = max(x0, ax0),
  //     qx1 = min(x1, ax1),
  //     qy0 = max(y0, ay0),
  //     qy1 = min(y1, ay1);
  // if (qx0 <= qx1 && qy0 <= qy1) {
  //     res += Q(qx0, qx1, qy0, qy1);
  // }
  return mem[x0][x1][y0][y1] = res;
}

int main() {
  cin >> n >> m;
  memset(cnt, 0, sizeof(cnt));
  memset(mem, -1, sizeof(mem));
  rep(i, 0, n) {
    rep(j, 0, m) {
      cin >> board[i][j];
      if (board[i][j] == 'o') {
        cnt[i + 1][j + 1]++;
      }
      cnt[i + 1][j + 1] += cnt[i][j + 1] + cnt[i + 1][j] - cnt[i][j];
    }
  }

  // rep(i,0,n+1) {
  //     rep(j,0,m+1) {
  //         cout << cnt[i][j] << " ";
  //     }
  //     cout << endl;
  // }

  rep(i, 0, n) {
    rep(j, 0, m) {
      if (board[i][j] == 'E') {
        cout << dp(i, i, j, j, 0, n - 1, 0, m - 1) << endl;
        return 0;
      }
    }
  }

  return 0;
}


Fixed submission:
#include <bits/stdc++.h>
using namespace std;
template <class T> int size(const T &x) { return x.size(); }
#define rep(i, a, b) for (__typeof(a) i = (a); i < (b); ++i)
#define iter(it, c)                                                            \
  for (__typeof((c).begin()) it = (c).begin(); it != (c).end(); ++it)
typedef pair<int, int> ii;
typedef vector<int> vi;
typedef vector<ii> vii;
typedef long long ll;
const int INF = 2147483647;

char board[110][110];
int cnt[110][110];
short mem[100][100][100][100]; // TODO: short?
int n, m;

#define Q(a, b, c, d)                                                          \
  (cnt[b + 1][d + 1] - cnt[b + 1][c] - cnt[a][d + 1] + cnt[a][c])

int dp(int x0, int x1, int y0, int y1, int ax0, int ax1, int ay0, int ay1) {

  if (mem[x0][x1][y0][y1] != -1) {
    return mem[x0][x1][y0][y1];
  }

  int res = 0;
  if (x0 > 0) {
    int add = 0;
    int qx0 = max(x0 - 1, ax0), qx1 = min(x0 - 1, ax1), qy0 = max(y0, ay0),
        qy1 = min(y1, ay1);
    if (qx0 <= qx1 && qy0 <= qy1)
      add = Q(qx0, qx1, qy0, qy1);
    res = max(res, add + dp(x0 - 1, x1, y0, y1, ax0, ax1 - 1, ay0, ay1));
  }
  if (x1 < n - 1) {
    int add = 0;
    int qx0 = max(x1 + 1, ax0), qx1 = min(x1 + 1, ax1), qy0 = max(y0, ay0),
        qy1 = min(y1, ay1);
    if (qx0 <= qx1 && qy0 <= qy1)
      add = Q(qx0, qx1, qy0, qy1);
    res = max(res, add + dp(x0, x1 + 1, y0, y1, ax0 + 1, ax1, ay0, ay1));
  }
  if (y0 > 0) {
    int add = 0;
    int qx0 = max(x0, ax0), qx1 = min(x1, ax1), qy0 = max(y0 - 1, ay0),
        qy1 = min(y0 - 1, ay1);
    if (qx0 <= qx1 && qy0 <= qy1)
      add = Q(qx0, qx1, qy0, qy1);
    res = max(res, add + dp(x0, x1, y0 - 1, y1, ax0, ax1, ay0, ay1 - 1));
  }
  if (y1 < m - 1) {
    int add = 0;
    int qx0 = max(x0, ax0), qx1 = min(x1, ax1), qy0 = max(y1 + 1, ay0),
        qy1 = min(y1 + 1, ay1);
    if (qx0 <= qx1 && qy0 <= qy1)
      add = Q(qx0, qx1, qy0, qy1);
    res = max(res, add + dp(x0, x1, y0, y1 + 1, ax0, ax1, ay0 + 1, ay1));
  }

  // int qx0 = max(x0, ax0),
  //     qx1 = min(x1, ax1),
  //     qy0 = max(y0, ay0),
  //     qy1 = min(y1, ay1);
  // if (qx0 <= qx1 && qy0 <= qy1) {
  //     res += Q(qx0, qx1, qy0, qy1);
  // }
  return mem[x0][x1][y0][y1] = res;
}

int main() {
  cin >> n >> m;
  memset(cnt, 0, sizeof(cnt));
  memset(mem, -1, sizeof(mem));
  rep(i, 0, n) {
    rep(j, 0, m) {
      cin >> board[i][j];
      if (board[i][j] == 'o') {
        cnt[i + 1][j + 1]++;
      }
      cnt[i + 1][j + 1] += cnt[i][j + 1] + cnt[i + 1][j] - cnt[i][j];
    }
  }

  // rep(i,0,n+1) {
  //     rep(j,0,m+1) {
  //         cout << cnt[i][j] << " ";
  //     }
  //     cout << endl;
  // }

  rep(i, 0, n) {
    rep(j, 0, m) {
      if (board[i][j] == 'E') {
        cout << dp(i, i, j, j, 0, n - 1, 0, m - 1) << endl;
        return 0;
      }
    }
  }

  return 0;
}