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

#include <algorithm>
#include <cmath>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <iostream>
#include <map>
#include <queue>
#include <set>
#include <sstream>
#include <stack>
#include <string>
#include <vector>

using namespace std;

#define FOR(i, k, n) for (int i = (k); i < (int)n; ++i)
#define REP(i, n) FOR(i, 0, n)
#define FORIT(i, c)                                                            \\
  for (__typeof((c).begin()) i = (c).begin(); i != (c).end(); ++i)
static const int MAX = 10000;
int n;
int p[41];
int t[41];
int memo[100][5];
int dfs(int k, int bals) {
  if (k > n)
    return (bals) ? p[k - 1] : 0;
  if (memo[k][bals] != -1)
    return memo[k][bals];
  int pos = p[k - 1];
  int time = t[k - 1];
  int ret = MAX + k;
  if (bals == 0) {
    int needtime = abs(pos - p[k]) * (bals + 1);
    if (needtime + time <= t[k]) {
      int d = dfs(k + 1, bals + 1);
      if (d < MAX)
        ret = d + abs(pos - p[k]);
      else
        ret = d;
    }
  } else if (bals == 3) {
    int needtime = pos * (bals + 1) + p[k];
    if (needtime + time <= t[k]) {
      int d = dfs(k + 1, 1);
      if (d < MAX)
        ret = d + pos + p[k];
      else
        ret = d;
    }
  } else {
    int need1 = abs(pos - p[k]) * (bals + 1);
    int need2 = pos * (bals + 1) + p[k];
    if (need1 + time <= t[k]) {
      int d = dfs(k + 1, bals + 1);
      if (d < MAX)
        ret = min(ret, d + abs(pos - p[k]));
      else
        ret = max(ret, d);
    }
    if (need2 + time <= t[k]) {
      int d = dfs(k + 1, 1);
      if (d < MAX)
        ret = min(ret, d + pos + p[k]);
      else
        ret = max(ret, d);
    }
  }
  return memo[k][bals] = ret;
}

int main() {
  while (cin >> n, n) {
    REP(i, n) cin >> p[i + 1] >> t[i + 1];
    memset(memo, -1, sizeof(memo));
    int ans = dfs(1, 0);
    if (ans > MAX)
      printf("NG %d\\n", ans - MAX);
    else
      printf("OK %d\\n", ans);
  }
  return 0;
}

Error: TLE

Fixed submission:

#include <algorithm>
#include <cmath>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <iostream>
#include <map>
#include <queue>
#include <set>
#include <sstream>
#include <stack>
#include <string>
#include <vector>

using namespace std;

#define FOR(i, k, n) for (int i = (k); i < (int)n; ++i)
#define REP(i, n) FOR(i, 0, n)
#define FORIT(i, c)                                                            \\
  for (__typeof((c).begin()) i = (c).begin(); i != (c).end(); ++i)
static const int MAX = 10000;
int n;
int p[41];
int t[41];
int dfs(int k, int bals) {
  if (k > n)
    return (bals) ? p[k - 1] : 0;
  int pos = p[k - 1];
  int time = t[k - 1];
  int ret = MAX + k;
  if (bals == 0) {
    int needtime = abs(pos - p[k]) * (bals + 1);
    if (needtime + time <= t[k]) {
      int d = dfs(k + 1, bals + 1);
      if (d < MAX)
        ret = d + abs(pos - p[k]);
      else
        ret = d;
    }
  } else if (bals == 3) {
    int needtime = pos * (bals + 1) + p[k];
    if (needtime + time <= t[k]) {
      int d = dfs(k + 1, 1);
      if (d < MAX)
        ret = d + pos + p[k];
      else
        ret = d;
    }
  } else {
    int need1 = abs(pos - p[k]) * (bals + 1);
    int need2 = pos * (bals + 1) + p[k];
    if (need1 + time <= t[k]) {
      int d = dfs(k + 1, bals + 1);
      if (d < MAX)
        ret = min(ret, d + abs(pos - p[k]));
      else
        ret = max(ret, d);
    }
    if (need2 + time <= t[k]) {
      int d = dfs(k + 1, 1);
      if (d < MAX)
        ret = min(ret, d + pos + p[k]);
      else
        ret = max(ret, d);
    }
  }
  return ret;
}

int main() {
  while (cin >> n, n) {
    REP(i, n) cin >> p[i + 1] >> t[i + 1];
    int ans = dfs(1, 0);
    if (ans > MAX)
      printf("NG %d\\n", ans - MAX);
    else
      printf("OK %d\\n", ans);
  }
  return 0;
}