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

#include <algorithm>
#include <cstdio>
#include <cstring>
#include <iostream>
#include <queue>
#include <vector>
#define INF 99999999
using namespace std;
typedef pair<int, int> P;
vector<P> point[7];
int x, y;
int dp[6][1001][6];
char mas[1001][1001];
int cx[6], ans;
int sp, ans1;
int solve(int i, int j, int z);
int main() {
  while (1) {
    for (int i = 0; i < 7; i++) {
      point[i].clear();
    }
    memset(cx, 0, sizeof(cx));
    ans1 = INF;
    sp = INF;
    cin >> x >> y;
    if (x == 0 && y == 0)
      break;
    for (int i = 0; i < y; i++)
      cin >> mas[i];
    for (int i = 0; i < y; i++) {
      for (int j = 0; j < x; j++) {
        if (mas[i][j] == 'S') {
          point[0].push_back(P(j, i));
        }
        if (mas[i][j] == 'G') {
          point[6].push_back(P(j, i));
        }
        if (mas[i][j] >= '1' && mas[i][j] <= '5') {
          point[mas[i][j] - '0'].push_back(P(j, i));
          cx[mas[i][j] - '0']++;
        }
      }
    }
    for (int i = 1; i <= 5; i++) {
      rotate(point + 1, point + 2, point + 6);
      rotate(cx + 1, cx + 2, cx + 6);
      memset(dp, -1, sizeof(dp));
      ans = solve(0, 0, 0);
      if (ans < ans1) {
        ans1 = ans;
        sp = i;
      }
    }
    if (ans1 == INF)
      cout << "NA" << endl;
    else
      cout << sp << " " << ans1 << endl;
  }
}
int solve(int i, int j, int z) {
  if (dp[i][j][z] >= 0)
    return dp[i][j][z];
  if (i == 4) {
    return abs(point[6][0].first - point[z][j].first) +
           abs(point[6][0].second - point[z][j].second);
  }
  int res = INF;
  for (int k = 0; k < cx[z + 1]; k++) {
    res = min(abs(point[z + 1][k].first - point[z][j].first) +
                  abs(point[z + 1][k].second - point[z][j].second) +
                  solve(i + 1, k, z + 1),
              res);
  }
  return dp[i][j][z] = res;
}

Error: TLE

Fixed submission:

#include <cmath>
#include <cstring>
#include <iostream>
#include <map>
#include <vector>
#define F first
#define S second
#define INF 1 << 28
using namespace std;

int w, h;
char c;
int sx, sy, gx, gy;
typedef pair<int, int> P;
vector<P> d[9];
map<P, map<int, int>> memo;

int cost(P now, P will, int cnt) {

  if (!cnt)
    now.F = sx, now.S = sy;
  else if (cnt == 4)
    will.F = gx, will.S = gy;

  return abs(will.F - now.F) + abs(will.S - now.S);
}

int solve(P p, int cnt) {

  if (memo[p][cnt])
    return memo[p][cnt];
  if (cnt == 5)
    return 0;

  int ret = INF, k = (p.F + 1) % 5;
  for (int i = 0; i < d[k].size(); i++)
    ret = min(solve(P(k, i), cnt + 1) + cost(d[p.F][p.S], d[k][i], cnt), ret);

  return memo[p][cnt] = ret;
}

int main() {

  while (true) {
    cin >> w >> h;
    if (!w && !h)
      break;

    for (int i = 0; i < 9; i++)
      d[i].clear();

    for (int i = 0; i < h; i++) {
      for (int j = 0; j < w; j++) {
        cin >> c;
        if (c == 'S')
          sx = j, sy = i;
        else if (c == 'G')
          gx = j, gy = i;
        else if (c != '.')
          d[c - '1'].push_back(P(j, i));
      }
    }

    memo.clear();

    P p(INF, INF);
    for (int i = 0; i < 5; i++)
      if (p.S > solve(P(i, 0), 0))
        p.F = i + 1, p.S = solve(P(i, 0), 0);

    if (p.F == INF)
      cout << "NA" << endl;
    else
      cout << p.F << " " << p.S << endl;
  }
}