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


#include <bits/stdc++.h>
using namespace std;
using ll = long long;
using vi = vector<int>;
using vvi = vector<vi>;
using pii = pair<int, int>;
#define rep(i, n) for (int i = 0; i < n; i++)
#define range(i, a, n) for (int i = a; i < n; i++)
#define all(a) a.begin(), a.end()
#define rall(a) a.rbegin(), a.rend()
#define INF 1e9
#define EPS 1e-9
#define MOD (1e9 + 7)
void put(string d) {}
template <class H, class... T> void put(string d, H &h, T &...t) {
  cout << h;
  if (sizeof...(t))
    cout << d;
  put(d, t...);
}
template <class T> void puti(T &a, string d = " ") {
  bool f = 1;
  for (auto &_ : a)
    cout << (exchange(f, 0) ? "" : d) << _;
  cout << endl;
}
template <class T> void putii(T &a, string d = " ") {
  for (auto &_ : a)
    puti(_, d);
}

vector<pii> b;
using data = tuple<int, int, int, int, int>;
map<data, pair<bool, int>> memo;

pair<bool, int> solve(int pos, int index, int lefttime, int carry,
                      int totalDist) {
  data d = make_tuple(pos, index, lefttime, carry, totalDist);
  if (memo.find(d) != memo.end())
    return memo[d];
  // cout<<pos<<" "<<index<<" "<<lefttime<<" "<<carry<<" "<<totalDist<<endl;
  if (index == b.size())
    return memo[d] = make_pair(true, totalDist + pos);
  int bpos = b[index].first;
  int bhigh = b[index].second - lefttime;
  int dist = abs(pos - bpos);
  int need = dist * (carry + 1);
  if (bhigh < need) {
    return memo[d] = make_pair(false, index + 1); // 目標を取れない
  } else {
    lefttime += bhigh;
  }
  if (carry == 2) { // 3つめを持った
    return memo[d] = solve(0, index + 1, lefttime + bpos * (carry + 2), 0,
                           totalDist + dist + bpos);
  }
  auto ans_next = solve(bpos, index + 1, lefttime, carry + 1, totalDist + dist);
  need = bpos * (carry + 2);
  auto ans_home =
      solve(0, index + 1, lefttime + need, 0, totalDist + dist + bpos);
  if (ans_home.first == false and ans_next.first == false) {
    if (ans_home.second > ans_next.second) {
      return memo[d] = ans_home;
    } else {
      return memo[d] = ans_next;
    }
  }
  if (ans_home.first == false)
    return memo[d] = ans_next;
  if (ans_next.first == false)
    return memo[d] = ans_home;
  if (ans_next.second > ans_home.second)
    return memo[d] = ans_home;
  else
    return memo[d] = ans_next;
}

int main() {
  int n;
  while (cin >> n, n) {
    memo.clear();
    b.resize(n);
    for (auto &i : b)
      cin >> i.first >> i.second;
    auto res = solve(0, 0, 0, 0, 0);
    cout << (res.first ? "OK " : "NG ") << res.second << endl;
  }
  return 0;
}


Error: TLE

Fixed submission:


#include <bits/stdc++.h>
using namespace std;
using ll = long long;
using vi = vector<int>;
using vvi = vector<vi>;
using pii = pair<int, int>;
#define rep(i, n) for (int i = 0; i < n; i++)
#define range(i, a, n) for (int i = a; i < n; i++)
#define all(a) a.begin(), a.end()
#define rall(a) a.rbegin(), a.rend()
#define INF 1e9
#define EPS 1e-9
#define MOD (1e9 + 7)
void put(string d) {}
template <class H, class... T> void put(string d, H &h, T &...t) {
  cout << h;
  if (sizeof...(t))
    cout << d;
  put(d, t...);
}
template <class T> void puti(T &a, string d = " ") {
  bool f = 1;
  for (auto &_ : a)
    cout << (exchange(f, 0) ? "" : d) << _;
  cout << endl;
}
template <class T> void putii(T &a, string d = " ") {
  for (auto &_ : a)
    puti(_, d);
}

vector<pii> b;

pair<bool, int> solve(int pos, int index, int lefttime, int carry,
                      int totalDist) {
  // cout<<pos<<" "<<index<<" "<<lefttime<<" "<<carry<<" "<<totalDist<<endl;
  if (carry == 4)
    return make_pair(false, index + 1);
  if (index == b.size()) { // 全て取ったら
    return make_pair(true, totalDist + pos);
  }
  int bpos = b[index].first;
  int bhigh = b[index].second - lefttime;
  int dist = abs(pos - bpos);
  int need = dist * (carry + 1);
  if (bhigh < need) {
    return make_pair(false, index + 1); // 目標を取れない
  } else {
    lefttime += bhigh;
  }
  auto ans_next = solve(bpos, index + 1, lefttime, carry + 1, totalDist + dist);
  need = bpos * (carry + 2);
  auto ans_home =
      solve(0, index + 1, lefttime + need, 0, totalDist + dist + bpos);
  if (ans_home.first == false) {
    return ans_next;
  }
  if (ans_next.first == false) {
    return ans_home;
  }
  if (ans_next.second > ans_home.second) {
    return ans_home;
  } else
    return ans_next;
}

int main() {
  int n;
  while (cin >> n, n) {
    b.resize(n);
    for (auto &i : b)
      cin >> i.first >> i.second;
    auto res = solve(0, 0, 0, 0, 0);
    cout << (res.first ? "OK " : "NG ") << res.second << endl;
  }
  return 0;
}