Problem p04009 (C++)

Buggy submission (status: Memory Limit Exceeded):
#include <algorithm>
#include <cstdio>

#define Rep(i, n) for (int i = 1; i <= n; i++)
#define Rep0(i, n) for (int i = 0; i <= n; i++)
#define RepG(i, x) for (int i = head[x]; i; i = edge[i].next)
#define v edge[i].to

using namespace std;

const int N = 110;

char g[N][N];
short s[N][N];
short f[N][N][N][N];

void inc(short &a, short b) {
  if (b > a)
    a = b;
}

short get(int x1, int y1, int x2, int y2) {
  if (x1 > x2 || y1 > y2)
    return -10000;
  x1--, y1--;
  return s[x2][y2] - s[x2][y1] - s[x1][y2] + s[x1][y1];
}

int main() {
  int n, m;
  scanf("%d%d", &n, &m);
  int ex, ey;
  Rep(i, n) {
    scanf("%s", g[i] + 1);
    Rep(j, m) {
      s[i][j] = s[i][j - 1];
      if (g[i][j] == 'o')
        s[i][j]++;
      else if (g[i][j] == 'E')
        ex = i, ey = j;
    }
  }
  Rep(i, n) Rep(j, m) s[i][j] += s[i - 1][j];
  short ans = 0;
  Rep0(i, ex - 1) Rep0(j, ey - 1) Rep0(k, n - ex) Rep0(h, m - ey) {
    // printf("%d %d %d %d %d\n", i, j, k, h, (int)f[i][j][k][h]);
    int lx = max(1 + k, ex - i), rx = min(n - i, ex + k);
    int ly = max(1 + h, ey - j), ry = min(m - j, ey + h);
    short tmp = f[i][j][k][h];
    if (1 + k <= ex - i - 1 && ex - i - 1 <= n - i)
      inc(f[i + 1][j][k][h], tmp + get(ex - i - 1, ly, ex - i - 1, ry));
    if (1 + h <= ey - j - 1 && ey - j - 1 <= m - j)
      inc(f[i][j + 1][k][h], tmp + get(lx, ey - j - 1, rx, ey - j - 1));
    if (1 + k <= ex + k + 1 && ex + k + 1 <= n - i)
      inc(f[i][j][k + 1][h], tmp + get(ex + k + 1, ly, ex + k + 1, ry));
    if (1 + h <= ey + h + 1 && ey + h + 1 <= m - j)
      inc(f[i][j][k][h + 1], tmp + get(lx, ey + h + 1, rx, ey + h + 1));
    inc(ans, tmp);
  }

  printf("%d\n", (int)ans);

  return 0;
}


Fixed submission:
#include <algorithm>
#include <cstdio>

#define Rep(i, n) for (int i = 1; i <= n; i++)
#define Rep0(i, n) for (int i = 0; i <= n; i++)
#define RepG(i, x) for (int i = head[x]; i; i = edge[i].next)
#define v edge[i].to

using namespace std;

const int N = 101;

char g[N][N];
short s[N][N];
short f[N][N][N][N];

void inc(short &a, short b) {
  if (b > a)
    a = b;
}

short get(int x1, int y1, int x2, int y2) {
  if (x1 > x2 || y1 > y2)
    return -10000;
  x1--, y1--;
  return s[x2][y2] - s[x2][y1] - s[x1][y2] + s[x1][y1];
}

int main() {
  int n, m;
  scanf("%d%d", &n, &m);
  int ex, ey;
  Rep(i, n) {
    scanf("%s", g[i] + 1);
    Rep(j, m) {
      s[i][j] = s[i][j - 1];
      if (g[i][j] == 'o')
        s[i][j]++;
      else if (g[i][j] == 'E')
        ex = i, ey = j;
    }
  }
  Rep(i, n) Rep(j, m) s[i][j] += s[i - 1][j];
  short ans = 0;
  Rep0(i, ex - 1) Rep0(j, ey - 1) Rep0(k, n - ex) Rep0(h, m - ey) {
    // printf("%d %d %d %d %d\n", i, j, k, h, (int)f[i][j][k][h]);
    int lx = max(1 + k, ex - i), rx = min(n - i, ex + k);
    int ly = max(1 + h, ey - j), ry = min(m - j, ey + h);
    short tmp = f[i][j][k][h];
    if (1 + k <= ex - i - 1 && ex - i - 1 <= n - i)
      inc(f[i + 1][j][k][h], tmp + get(ex - i - 1, ly, ex - i - 1, ry));
    if (1 + h <= ey - j - 1 && ey - j - 1 <= m - j)
      inc(f[i][j + 1][k][h], tmp + get(lx, ey - j - 1, rx, ey - j - 1));
    if (1 + k <= ex + k + 1 && ex + k + 1 <= n - i)
      inc(f[i][j][k + 1][h], tmp + get(ex + k + 1, ly, ex + k + 1, ry));
    if (1 + h <= ey + h + 1 && ey + h + 1 <= m - j)
      inc(f[i][j][k][h + 1], tmp + get(lx, ey + h + 1, rx, ey + h + 1));
    inc(ans, tmp);
  }

  printf("%d\n", (int)ans);

  return 0;
}