Problem p04009 (C++)

Buggy submission (status: Memory Limit Exceeded):
#include <algorithm>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <iostream>
using namespace std;

#define re return
#define in inline
#define inc(l, i, r) for (i = l; i < r; ++i)

const short mxn = 1 << 7;

short h, w, xe, ye, a[mxn][mxn], s[mxn][mxn], f[mxn][mxn][mxn][mxn];
char str[mxn];

in void upd(short &a, short b) { a < b ? a = b : 0; }

in short sum(short x1, short x2, short y1, short y2) {
  re s[x2][y2] + s[x1 - 1][y1 - 1] - s[x2][y1 - 1] - s[x1 - 1][y2];
}

int main() {
  short i, j, k, l, ans = 0;
  cin >> h >> w;
  scanf("\n");
  inc(1, i, h + 1) {
    scanf("%s", str);
    //        gets(str);
    inc(1, j, w + 1) switch (str[j - 1]) {
    case 'o':
      a[i][j] = 1;
      break;
    case 'E':
      xe = i, ye = j;
    }
  }
  inc(1, i, h + 1) inc(1, j, w + 1) s[i][j] =
      a[i][j] - s[i - 1][j - 1] + s[i][j - 1] + s[i - 1][j];

  inc(0, i, xe + 1) inc(0, j, ye + 1) inc(0, k, h - xe + 1)
      inc(0, l, w - ye + 1) {
    //        printf("%d %d %d %d : %d\n", i, j, k, l, f[i][j][k][l]);
    upd(ans, f[i][j][k][l]);
    if (i + k + 1 < xe)
      upd(f[i + 1][j][k][l],
          f[i][j][k][l] + sum(xe - i - 1, xe - i - 1, max(ye - j, l + 1),
                              min(ye + l, w - j)));
    if (xe + i + k < h)
      upd(f[i][j][k + 1][l],
          f[i][j][k][l] + sum(xe + k + 1, xe + k + 1, max(ye - j, l + 1),
                              min(ye + l, w - j)));
    if (j + l + 1 < ye)
      upd(f[i][j + 1][k][l],
          f[i][j][k][l] + sum(max(xe - i, k + 1), min(xe + k, h - i),
                              ye - j - 1, ye - j - 1));
    if (ye + j + l < w)
      upd(f[i][j][k][l + 1],
          f[i][j][k][l] + sum(max(xe - i, k + 1), min(xe + k, h - i),
                              ye + l + 1, ye + l + 1));
  }
  cout << ans << "\n";
  re 0;
}


Fixed submission:
#include <algorithm>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <iostream>
using namespace std;

#define re return
#define in inline
#define inc(l, i, r) for (i = l; i < r; ++i)

const short mxn = 101;

short h, w, xe, ye, a[mxn][mxn], s[mxn][mxn], f[mxn][mxn][mxn][mxn];
char str[mxn];

in void upd(short &a, short b) { a < b ? a = b : 0; }

in short sum(short x1, short x2, short y1, short y2) {
  re s[x2][y2] + s[x1 - 1][y1 - 1] - s[x2][y1 - 1] - s[x1 - 1][y2];
}

int main() {
  short i, j, k, l, ans = 0;
  cin >> h >> w;
  scanf("\n");
  inc(1, i, h + 1) {
    scanf("%s", str);
    //        gets(str);
    inc(1, j, w + 1) switch (str[j - 1]) {
    case 'o':
      a[i][j] = 1;
      break;
    case 'E':
      xe = i, ye = j;
    }
  }
  inc(1, i, h + 1) inc(1, j, w + 1) s[i][j] =
      a[i][j] - s[i - 1][j - 1] + s[i][j - 1] + s[i - 1][j];

  inc(0, i, xe + 1) inc(0, j, ye + 1) inc(0, k, h - xe + 1)
      inc(0, l, w - ye + 1) {
    //        printf("%d %d %d %d : %d\n", i, j, k, l, f[i][j][k][l]);
    upd(ans, f[i][j][k][l]);
    if (i + k + 1 < xe)
      upd(f[i + 1][j][k][l],
          f[i][j][k][l] + sum(xe - i - 1, xe - i - 1, max(ye - j, l + 1),
                              min(ye + l, w - j)));
    if (xe + i + k < h)
      upd(f[i][j][k + 1][l],
          f[i][j][k][l] + sum(xe + k + 1, xe + k + 1, max(ye - j, l + 1),
                              min(ye + l, w - j)));
    if (j + l + 1 < ye)
      upd(f[i][j + 1][k][l],
          f[i][j][k][l] + sum(max(xe - i, k + 1), min(xe + k, h - i),
                              ye - j - 1, ye - j - 1));
    if (ye + j + l < w)
      upd(f[i][j][k][l + 1],
          f[i][j][k][l] + sum(max(xe - i, k + 1), min(xe + k, h - i),
                              ye + l + 1, ye + l + 1));
  }
  cout << ans << "\n";
  re 0;
}