Problem p04009 (C++)

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

const int maxn = 100 + 10;

int sumrow[maxn][maxn];
int sumcol[maxn][maxn];
int R, C;
char save[maxn][maxn];

int X, Y;

short dp[maxn][maxn][maxn][maxn];

int main() {
  // freopen("./test.txt","r",stdin);
  scanf("%d %d", &R, &C);
  for (int i = 1; i <= R; ++i) {
    scanf("%s", save[i] + 1);
    for (int j = 1; j <= C; ++j)
      if (save[i][j] == 'E')
        X = i, Y = j;
  }
  memset(sumrow, 0, sizeof(sumrow));
  memset(sumcol, 0, sizeof(sumcol));

  for (int r = 1; r <= R; ++r) {
    sumrow[r][0] = 0;
    for (int c = 1; c <= C; ++c) {
      sumrow[r][c] = sumrow[r][c - 1];
      if (save[r][c] == 'o')
        sumrow[r][c]++;
    }
  }

  for (int c = 1; c <= C; ++c) {
    sumcol[c][0] = 0;
    for (int r = 1; r <= R; ++r) {
      sumcol[c][r] = sumcol[c][r - 1];
      if (save[r][c] == 'o')
        sumcol[c][r]++;
    }
  }

  memset(dp, 0, sizeof(dp));
  for (int up = X; up >= 1; --up)
    for (int lft = Y; lft >= 1; --lft)
      for (int down = X; down <= R; ++down)
        for (int right = Y; right <= C; ++right) {
          int blft = right - Y + 1;
          int bright = C - (Y - lft);
          int bup = down - X + 1;
          int bdown = R - (X - up);
          if (up > 1) // to up-1
          {

            short add;
            if (up - 1 < bup)
              add = 0;
            else {
              int tL = max(blft, lft);
              int tR = min(bright, right);
              if (tL > tR)
                add = 0;
              else
                add = sumrow[up - 1][tR] - sumrow[up - 1][tL - 1];
            }
            dp[up - 1][lft][down][right] =
                max(dp[up - 1][lft][down][right],
                    (short)(dp[up][lft][down][right] + add));
          }
          if (down < R) {
            short add;
            if (down + 1 > bdown)
              add = 0;
            else {
              int tL = max(blft, lft);
              int tR = min(bright, right);
              if (tL > tR)
                add = 0;
              else
                add = sumrow[down + 1][tR] - sumrow[down + 1][tL - 1];
            }
            dp[up][lft][down + 1][right] =
                max(dp[up][lft][down + 1][right],
                    (short)(dp[up][lft][down][right] + add));
          }

          if (lft > 1) {
            short add;
            if (lft - 1 < blft)
              add = 0;
            else {
              int tL = max(bup, up);
              int tR = min(bdown, down);
              if (tL > tR)
                add = 0;
              else
                add = sumcol[lft - 1][tR] - sumcol[lft - 1][tL - 1];
            }
            dp[up][lft - 1][down][right] =
                max(dp[up][lft - 1][down][right],
                    (short)(dp[up][lft][down][right] + add));
          }

          if (right < C) {
            short add;
            if (right + 1 > bright)
              add = 0;
            else {
              int tL = max(bup, up);
              int tR = min(bdown, down);
              if (tL > tR)
                add = 0;
              else
                add = sumcol[right + 1][tR] - sumcol[right + 1][tL - 1];
            }
            dp[up][lft][down][right + 1] =
                max(dp[up][lft][down][right + 1],
                    (short)(dp[up][lft][down][right] + add));
          }
        }
  int res = dp[1][1][R][C];
  printf("%d\n", res);

  return 0;
}

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

const int maxn = 100 + 1;

int sumrow[maxn][maxn];
int sumcol[maxn][maxn];
int R, C;
char save[maxn][maxn];

int X, Y;

short dp[maxn][maxn][maxn][maxn];

int main() {
  // freopen("./test.txt","r",stdin);
  scanf("%d %d", &R, &C);
  for (int i = 1; i <= R; ++i) {
    scanf("%s", save[i] + 1);
    for (int j = 1; j <= C; ++j)
      if (save[i][j] == 'E')
        X = i, Y = j;
  }
  memset(sumrow, 0, sizeof(sumrow));
  memset(sumcol, 0, sizeof(sumcol));

  for (int r = 1; r <= R; ++r) {
    sumrow[r][0] = 0;
    for (int c = 1; c <= C; ++c) {
      sumrow[r][c] = sumrow[r][c - 1];
      if (save[r][c] == 'o')
        sumrow[r][c]++;
    }
  }

  for (int c = 1; c <= C; ++c) {
    sumcol[c][0] = 0;
    for (int r = 1; r <= R; ++r) {
      sumcol[c][r] = sumcol[c][r - 1];
      if (save[r][c] == 'o')
        sumcol[c][r]++;
    }
  }

  memset(dp, 0, sizeof(dp));
  for (int up = X; up >= 1; --up)
    for (int lft = Y; lft >= 1; --lft)
      for (int down = X; down <= R; ++down)
        for (int right = Y; right <= C; ++right) {
          int blft = right - Y + 1;
          int bright = C - (Y - lft);
          int bup = down - X + 1;
          int bdown = R - (X - up);
          if (up > 1) // to up-1
          {

            short add;
            if (up - 1 < bup)
              add = 0;
            else {
              int tL = max(blft, lft);
              int tR = min(bright, right);
              if (tL > tR)
                add = 0;
              else
                add = sumrow[up - 1][tR] - sumrow[up - 1][tL - 1];
            }
            dp[up - 1][lft][down][right] =
                max(dp[up - 1][lft][down][right],
                    (short)(dp[up][lft][down][right] + add));
          }
          if (down < R) {
            short add;
            if (down + 1 > bdown)
              add = 0;
            else {
              int tL = max(blft, lft);
              int tR = min(bright, right);
              if (tL > tR)
                add = 0;
              else
                add = sumrow[down + 1][tR] - sumrow[down + 1][tL - 1];
            }
            dp[up][lft][down + 1][right] =
                max(dp[up][lft][down + 1][right],
                    (short)(dp[up][lft][down][right] + add));
          }

          if (lft > 1) {
            short add;
            if (lft - 1 < blft)
              add = 0;
            else {
              int tL = max(bup, up);
              int tR = min(bdown, down);
              if (tL > tR)
                add = 0;
              else
                add = sumcol[lft - 1][tR] - sumcol[lft - 1][tL - 1];
            }
            dp[up][lft - 1][down][right] =
                max(dp[up][lft - 1][down][right],
                    (short)(dp[up][lft][down][right] + add));
          }

          if (right < C) {
            short add;
            if (right + 1 > bright)
              add = 0;
            else {
              int tL = max(bup, up);
              int tR = min(bdown, down);
              if (tL > tR)
                add = 0;
              else
                add = sumcol[right + 1][tR] - sumcol[right + 1][tL - 1];
            }
            dp[up][lft][down][right + 1] =
                max(dp[up][lft][down][right + 1],
                    (short)(dp[up][lft][down][right] + add));
          }
        }
  int res = dp[1][1][R][C];
  printf("%d\n", res);

  return 0;
}