Problem p00547 (C++) — buggy submission, verdict: Memory Limit Exceeded

#include <algorithm>
#include <cstdio>
#pragma warning(disable : 4996)
using namespace std;
int dir[] = {0, 1, 0, -1};
short H, W, a[1009][1009], dp[1009][1009][259];
bool used[1009][1009];
short solve(int x, int y) {
  if (x == H && y == W)
    return 0;
  int bit = used[x][y] + 2 * used[x - 1][y] + 4 * used[x][y - 1] +
            8 * used[x - 1][y + 1] + 16 * used[x + 1][y - 1] +
            32 * used[x - 1][y - 1] + 64 * used[x][y + 1] +
            128 * used[x + 1][y];
  if (dp[x][y][bit] != 32767)
    return dp[x][y][bit];
  short ret = 32767;
  for (int i = 0; i < 2; i++) {
    int tx = x + dir[i], ty = y + dir[i ^ 1];
    if (tx <= H && ty <= W) {
      short val = 0, rbit = 0;
      if (!used[tx][ty])
        val = a[tx][ty], used[tx][ty] = true, rbit = 16;
      for (int j = 0; j < 4; j++) {
        int ux = tx + dir[j], uy = ty + dir[j ^ 1];
        if (!used[ux][uy]) {
          used[ux][uy] = true;
          val += a[ux][uy];
          rbit |= 1 << j;
        }
      }
      for (int j = 0; j < 4; j++) {
        int ux = tx + dir[j], uy = ty + dir[j ^ 1];
        if (rbit & (1 << j))
          val -= a[ux][uy], used[ux][uy] = false;
        ret = min(ret, (short)(val + solve(tx, ty)));
        if (rbit & (1 << j))
          val += a[ux][uy], used[ux][uy] = true;
      }
      for (int j = 0; j < 4; j++) {
        if (rbit & (1 << j))
          used[tx + dir[j]][ty + dir[j ^ 1]] = false;
      }
      if (rbit & 16)
        used[tx][ty] = false;
    }
  }
  return dp[x][y][bit] = ret;
}
char buf[1009];
int main() {
  scanf("%hd%hd", &H, &W);
  for (int i = 0; i < H; i++) {
    scanf("%s", buf);
    for (int j = 0; j < W; j++) {
      if (buf[j] != '.')
        a[i + 1][j + 1] = buf[j] - 48;
      fill(dp[i + 1][j + 1], dp[i + 1][j + 1] + 256, 32767);
    }
  }
  int ret = solve(1, 1);
  printf("%hd\\n", ret);
  return 0;
}

Error: MLE

Fixed submission:

#include <algorithm>
#include <cstdio>
#pragma warning(disable : 4996)
using namespace std;
int dir[] = {0, 1, 0, -1};
short H, W, a[1009][1009], dp[1009][1009][519];
bool used[1009][1009];
short solve(int x, int y) {
  if (x == H && y == W)
    return 0;
  int bit = used[x][y] + 2 * used[x - 1][y] + 4 * used[x][y - 1] +
            8 * used[x - 1][y + 1] + 16 * used[x + 1][y - 1] +
            32 * used[x - 1][y - 1] + 64 * used[x][y + 1] +
            128 * used[x + 1][y] + 256 * used[x + 1][y + 1];
  if (dp[x][y][bit] != 32767)
    return dp[x][y][bit];
  short ret = 32767;
  for (int i = 0; i < 2; i++) {
    int tx = x + dir[i], ty = y + dir[i ^ 1];
    if (tx <= H && ty <= W) {
      short val = 0, rbit = 0;
      if (!used[tx][ty])
        val = a[tx][ty], used[tx][ty] = true, rbit = 16;
      for (int j = 0; j < 4; j++) {
        int ux = tx + dir[j], uy = ty + dir[j ^ 1];
        if (!used[ux][uy]) {
          used[ux][uy] = true;
          val += a[ux][uy];
          rbit |= 1 << j;
        }
      }
      for (int j = 0; j < 4; j++) {
        int ux = tx + dir[j], uy = ty + dir[j ^ 1];
        if (rbit & (1 << j))
          val -= a[ux][uy], used[ux][uy] = false;
        ret = min(ret, (short)(val + solve(tx, ty)));
        if (rbit & (1 << j))
          val += a[ux][uy], used[ux][uy] = true;
      }
      for (int j = 0; j < 4; j++) {
        if (rbit & (1 << j))
          used[tx + dir[j]][ty + dir[j ^ 1]] = false;
      }
      if (rbit & 16)
        used[tx][ty] = false;
    }
  }
  return dp[x][y][bit] = ret;
}
char buf[1009];
int main() {
  scanf("%hd%hd", &H, &W);
  for (int i = 0; i < H; i++) {
    scanf("%s", buf);
    for (int j = 0; j < W; j++) {
      if (buf[j] != '.')
        a[i + 1][j + 1] = buf[j] - 48;
      fill(dp[i + 1][j + 1], dp[i + 1][j + 1] + 512, 32767);
    }
  }
  int ret = solve(1, 1);
  printf("%hd\\n", ret);
  return 0;
}