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

#include <bits/stdc++.h>
using namespace std;
const int INF = 1 << 28;

int w, h;
vector<pair<int, int>> b[7];
vector<pair<int, int>> v[6];

int dist(pair<int, int> p1, pair<int, int> p2) {
  return abs(p1.first - p2.first) + abs(p1.second - p2.second);
}

int dp[6][1000];

void solve() {
  v[0] = b[0];
  v[5] = b[6];

  pair<int, int> res(INF, INF);

  for (int fi = 1; fi <= 5; fi++) {
    for (int i = 1; i <= 4; i++) {
      int x = (fi + i - 1) % 5 + 1;
      v[i] = b[x];
    }

    fill((int *)dp, (int *)dp + 6000, INF);
    dp[0][0] = 0;

    for (int i = 0; i < 6; i++) {
      for (int j = 0; j < v[i].size(); j++) {
        for (int k = 0; k < v[i + 1].size(); k++) {
          dp[i + 1][k] =
              min(dp[i + 1][k], dp[i][j] + dist(v[i][j], v[i + 1][k]));
        }
      }
    }

    res = min(res, make_pair(dp[5][0], fi));
  }

  if (res.first == INF)
    puts("NA");
  else
    printf("%d %d\\n", res.second, res.first);
}

int main() {
  char c;
  while (scanf("%d %d", &w, &h), w) {
    for (int i = 0; i < 7; i++) {
      b[i].clear();
    }
    for (int i = 0; i < h; i++) {
      for (int j = 0; j < w; j++) {
        pair<int, int> p(i, j);
        scanf(" %c", &c);
        switch (c) {
        case 'S':
          b[0].push_back(p);
          break;

        case 'G':
          b[6].push_back(p);
          break;

        case '.':
          break;

        default:
          b[c - '0'].push_back(p);
        }
      }
    }
    solve();
  }
}

Error: MLE

Fixed submission:

#include <bits/stdc++.h>
using namespace std;
const int dx[] = {-1, 0, 1, 0};
const int dy[] = {0, -1, 0, 1};
const int INF = 1 << 28;

int h, w;
int grid[1000][1000];
int d[1000][1000][1 << 5];

int sx, sy, gx, gy;

bool ok(int i, int j) { return i >= 0 && j >= 0 && i < h && j < w; }

void solve() {
  // turn, first
  pair<int, int> mini(INF, INF);
  for (int first = 0; first < 5; first++) {
    fill((int *)d, (int *)d + 1000 * 1000 * (1 << 5), INF);
    // turn, x, y, have
    queue<tuple<int, int, int, int>> que;
    que.push(make_tuple(0, sx, sy, 1 << first));
    d[sx][sy][1 << first] = 0;
    while (que.size()) {
      auto st = que.front();
      que.pop();
      int turn = get<0>(st);
      int x = get<1>(st);
      int y = get<2>(st);
      int z = get<3>(st);
      if (d[x][y][z] < turn)
        continue;
      if (x == gx && y == gy && z == (1 << 5) - 1)
        break;
      // printf("%d %d %d %d\\n", turn, x, y, z);

      for (int dir = 0; dir < 4; dir++) {
        int nx = x + dx[dir];
        int ny = y + dy[dir];
        if (!ok(nx, ny))
          continue;
        int nz = z;
        if (grid[nx][ny]) {
          int t = grid[nx][ny] - 1;
          t = 1 << t;
          int tx = (t == 1) ? (1 << 4) : (t >> 1);
          // printf("%d %d\\n", t, tx);
          if (nz & tx)
            nz |= t;
        }

        if (d[nx][ny][nz] > turn + 1) {
          d[nx][ny][nz] = turn + 1;
          que.push(make_tuple(turn + 1, nx, ny, nz));
        }
      }
    }
    mini = min(mini, make_pair(d[gx][gy][(1 << 5) - 1], first));
  }
  if (mini.first == INF)
    puts("NA");
  else
    printf("%d %d\\n", ++mini.second, mini.first);
}

int main() {
  while (scanf("%d %d", &w, &h), w) {
    memset(grid, 0, sizeof(grid));
    for (int i = 0; i < h; i++) {
      for (int j = 0; j < w; j++) {
        char c;
        scanf(" %c", &c);
        switch (c) {
        case 'S':
          sx = i;
          sy = j;
          break;
        case 'G':
          gx = i;
          gy = j;
          break;
        case '.':
          break;
        default:
          grid[i][j] = c - '0';
          break;
        }
      }
    }
    solve();
  }

  return 0;
}