Problem p04009 (C++)

Buggy submission (status: Memory Limit Exceeded):
#include <cstdio>
#include <cstring>
#define maxn 105
#define max(a, b) ((a) > (b) ? (a) : (b))
#define min(a, b) ((a) < (b) ? (a) : (b))
int n, m, dp[maxn][maxn][maxn][maxn], sumr[maxn][maxn], sumc[maxn][maxn], ex,
    ey, ans;
char s[maxn][maxn];
int main() {
  scanf("%d%d", &n, &m);
  for (int i = 1; i <= n; i++)
    scanf("%s", s[i] + 1);
  for (int i = 1; i <= n; i++)
    for (int j = 1; j <= m; j++) {
      sumr[i][j] = sumr[i][j - 1];
      sumc[i][j] = sumc[i - 1][j];
      if (s[i][j] == 'E')
        ex = i, ey = j;
      if (s[i][j] == 'o')
        sumr[i][j]++, sumc[i][j]++;
    }
  int L = ey - 1, R = m - ey, U = ex - 1, D = n - ex;
  memset(dp, -1, sizeof(dp));
  dp[0][0][0][0] = 0;
  for (int l = 0; l <= L; l++)
    for (int r = 0; r <= R; r++)
      for (int u = 0; u <= U; u++)
        for (int d = 0; d <= D; d++) {
          int tmp = dp[l][r][u][d];
          if (tmp == -1)
            continue;
          ans = max(tmp, ans);
          int up = max(ex - u, d + 1), dn = min(ex + d, n - u),
              le = max(ey - l, r + 1), ri = min(ey + r, m - l);
          if (up > dn || le > ri)
            continue;
          if (u < U - d)
            dp[l][r][u + 1][d] =
                max(dp[l][r][u + 1][d],
                    tmp + sumr[ex - u - 1][ri] - sumr[ex - u - 1][le - 1]);
          if (d < D - u)
            dp[l][r][u][d + 1] =
                max(dp[l][r][u][d + 1],
                    tmp + sumr[ex + d + 1][ri] - sumr[ex + d + 1][le - 1]);
          if (r < R - l)
            dp[l][r + 1][u][d] =
                max(dp[l][r + 1][u][d],
                    tmp + sumc[dn][ey + r + 1] - sumc[up - 1][ey + r + 1]);
          if (l < L - r)
            dp[l + 1][r][u][d] =
                max(dp[l + 1][r][u][d],
                    tmp + sumc[dn][ey - l - 1] - sumc[up - 1][ey - l - 1]);
        }
  printf("%d\n", ans);
}

Fixed submission:
#include <cstdio>
#include <cstring>
#define maxn 105
#define max(a, b) ((a) > (b) ? (a) : (b))
#define min(a, b) ((a) < (b) ? (a) : (b))
int n, m, sumr[maxn][maxn], sumc[maxn][maxn], ex, ey, ans;
short dp[maxn][maxn][maxn][maxn];
char s[maxn][maxn];
int main() {
  scanf("%d%d", &n, &m);
  for (int i = 1; i <= n; i++)
    scanf("%s", s[i] + 1);
  for (int i = 1; i <= n; i++)
    for (int j = 1; j <= m; j++) {
      sumr[i][j] = sumr[i][j - 1];
      sumc[i][j] = sumc[i - 1][j];
      if (s[i][j] == 'E')
        ex = i, ey = j;
      if (s[i][j] == 'o')
        sumr[i][j]++, sumc[i][j]++;
    }
  int L = ey - 1, R = m - ey, U = ex - 1, D = n - ex;
  memset(dp, -1, sizeof(dp));
  dp[0][0][0][0] = 0;
  for (int l = 0; l <= L; l++)
    for (int r = 0; r <= R; r++)
      for (int u = 0; u <= U; u++)
        for (int d = 0; d <= D; d++) {
          int tmp = dp[l][r][u][d];
          if (tmp == -1)
            continue;
          ans = max(tmp, ans);
          int up = max(ex - u, d + 1), dn = min(ex + d, n - u),
              le = max(ey - l, r + 1), ri = min(ey + r, m - l);
          if (up > dn || le > ri)
            continue;
          if (u < U - d)
            dp[l][r][u + 1][d] =
                max(dp[l][r][u + 1][d],
                    tmp + sumr[ex - u - 1][ri] - sumr[ex - u - 1][le - 1]);
          if (d < D - u)
            dp[l][r][u][d + 1] =
                max(dp[l][r][u][d + 1],
                    tmp + sumr[ex + d + 1][ri] - sumr[ex + d + 1][le - 1]);
          if (r < R - l)
            dp[l][r + 1][u][d] =
                max(dp[l][r + 1][u][d],
                    tmp + sumc[dn][ey + r + 1] - sumc[up - 1][ey + r + 1]);
          if (l < L - r)
            dp[l + 1][r][u][d] =
                max(dp[l + 1][r][u][d],
                    tmp + sumc[dn][ey - l - 1] - sumc[up - 1][ey - l - 1]);
        }
  printf("%d\n", ans);
}