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

#include <algorithm>
#include <cstring>
#include <iostream>
#include <map>
#include <set>
#include <sstream>
#include <string>
#include <vector>

#define REP(i, k, n) for (int i = k; i < n; i++)
#define rep(i, n) for (int i = 0; i < n; i++)
#define INF 1 << 30
#define pb push_back
#define mp make_pair

using namespace std;
typedef long long ll;
typedef pair<int, int> P;

int dp[50][4];

int main() {
  int n;
  while (cin >> n && n) {

    vector<int> p(n + 1), t(n + 1);
    rep(i, n) cin >> p[i + 1] >> t[i + 1];

    rep(i, 50) rep(j, 4) dp[i][j] = INF;

    int id = -1;
    dp[0][0] = 0;
    rep(i, n) {
      int d = abs(p[i + 1] - p[i]);
      bool flag = true;

      rep(j, 4) {
        if (dp[i][j] == INF)
          continue;

        if (j < 3 && d * (j + 1) <= t[i + 1] - t[i]) {
          flag = false;
          dp[i + 1][j + 1] = min(dp[i + 1][j + 1], dp[i][j] + d);
        }

        if (p[i] * (j + 1) + p[i + 1] <= t[i + 1] - t[i]) {
          flag = false;
          dp[i + 1][1] = min(dp[i + 1][1], dp[i][j] + p[i] + p[i + 1]);
        }
      }

      if (flag) {
        id = i + 1;
        break;
      }
    }

    if (id != -1)
      cout << "NG " << id << endl;
    else {
      int ans = INF;
      rep(j, 4) { ans = min(ans, dp[n][j] + p[n]); }
      cout << "OK " << ans << endl;
    }
  }

  return 0;
}

Error: MLE

Fixed submission:

#include <algorithm>
#include <cstring>
#include <iostream>
#include <map>
#include <set>
#include <sstream>
#include <string>
#include <vector>

#define REP(i, k, n) for (int i = k; i < n; i++)
#define rep(i, n) for (int i = 0; i < n; i++)
#define INF 1 << 30
#define pb push_back
#define mp make_pair

using namespace std;
typedef long long ll;
typedef pair<int, int> P;

int dp[50][500005];
int cnt[50][500005];
int place[50][500005];

int main() {
  int n;
  while (cin >> n && n) {

    vector<int> p(n + 1), t(n + 1);
    rep(i, n) cin >> p[i + 1] >> t[i + 1];

    rep(i, 50) rep(j, 500005) dp[i][j] = INF;
    memset(cnt, 0, sizeof(cnt));
    memset(place, 0, sizeof(place));

    int id = -1;
    dp[0][0] = 0;
    rep(i, n) {
      REP(j, 1, 500005) {
        if (dp[i][j] == INF) {
          dp[i][j] = dp[i][j - 1];
          cnt[i][j] = cnt[i][j - 1];
          place[i][j] = place[i][j - 1];
        }
      }

      bool flag = true;
      rep(j, 500005) {
        if (cnt[i][j] <= 2) {
          int time = j + abs(p[i + 1] - place[i][j]) * (cnt[i][j] + 1);
          if (time == t[i + 1]) {
            flag = false;
            if (dp[i + 1][time] > dp[i][j] + abs(p[i + 1] - place[i][j])) {
              dp[i + 1][time] = dp[i][j] + abs(p[i + 1] - place[i][j]);
              cnt[i + 1][time] = cnt[i][j] + 1;
              place[i + 1][time] = p[i + 1];
            }

            int ntime = time + abs(p[i + 1]) * (cnt[i][j] + 2);
            if (dp[i + 1][ntime] >
                dp[i][j] + abs(p[i + 1] - place[i][j]) + abs(p[i + 1])) {
              dp[i + 1][ntime] =
                  dp[i][j] + abs(p[i + 1] - place[i][j]) + abs(p[i + 1]);
              cnt[i + 1][ntime] = 0;
              place[i + 1][ntime] = 0;
            }
          }
        }
      }

      if (flag) {
        id = i + 1;
        break;
      }
    }

    if (id != -1) {
      cout << "NG " << id << endl;
    } else {
      int ans = INF;
      rep(j, 500005) {
        if (cnt[n][j] == 0) {
          ans = min(ans, dp[n][j]);
        }
      }

      if (ans == INF)
        cout << "NG " << n << endl;
      else
        cout << "OK " << ans << endl;

      // rep(i, n + 1) {
      // 	rep(j, 500) {
      // 		if(dp[i][j] == INF || dp[i][j] == 0) continue;
      // 		cout << i << "," << j << "(" << dp[i][j] << "," <<
      // cnt[i][j] << "," << place[i][j] << ") ";
      // 	}
      // 	cout << endl;
      // }
    }
  }

  return 0;
}