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

#include <algorithm>
#include <bitset>
#include <chrono>
#include <cmath>
#include <cstdint>
#include <functional>
#include <iomanip>
#include <iostream>
#include <iterator>
#include <list>
#include <map>
#include <numeric>
#include <queue>
#include <random>
#include <set>
#include <sstream>
#include <stack>
#include <string>
#include <vector>

#define N_TIMES(i, n) for (uint64_t i = 0; i < n; ++i)
#define N_TIMES_REV(i, n) for (int64_t i = n - 1; i >= 0; --i)

template <typename T>
using maximum_heap = std::priority_queue<T, std::vector<T>, std::less<T>>;
template <typename T>
using minimum_heap = std::priority_queue<T, std::vector<T>, std::greater<T>>;

template <typename T>
std::istream &operator>>(std::istream &is, std::vector<T> &v) {
  for (typename std::vector<T>::size_type i = 0; i < v.size(); ++i) {
    is >> v[i];
  }
  return is;
}

using namespace std;

struct DPItem {
  uint64_t money, stock, price;
  DPItem(uint64_t money, uint64_t stock, uint64_t price)
      : money(money), stock(stock), price(price) {}
  uint64_t operator()() const { return money + stock * price; }
  bool operator<(const DPItem &rhs) const { return (*this)() < rhs(); }
  bool operator>(const DPItem &rhs) const { return (*this)() > rhs(); }
};

const uint64_t M = 1e+5;

int main() {
  uint64_t N;
  cin >> N;

  vector<uint64_t> A(N);
  cin >> A;

  vector<maximum_heap<DPItem>> dp(N + 1);
  dp[0].emplace(1000, 0, 0);
  N_TIMES(n, N) {
    uint64_t cnt = 0;
    while (!dp[n].empty() && cnt < M) {
      DPItem item = dp[n].top();
      dp[n].pop();
      // 何もしない
      dp[n + 1].push(item);
      ++cnt;

      // 全株売却
      if (item.stock > 0 && item.price < A[n]) {
        if ((n == N - 1) || (n < N - 1 && A[n] > A[n + 1])) {
          dp[n + 1].emplace(item.money + item.stock * A[n], 0, 0);
          ++cnt;
        }
      }

      // 最大購入
      uint64_t c = item.money / A[n];
      if (item.stock == 0 && c > 0) {
        if ((n == N - 1) || (n < N - 1 && A[n] < A[n + 1])) {
          dp[n + 1].emplace(item.money % A[n], item.stock + c, A[n]);
          ++cnt;
        }
      }
    }
  }

  uint64_t max_money = 0;
  while (!dp[N].empty()) {
    DPItem item = dp[N].top();
    dp[N].pop();
    max_money = max(max_money, item());
  }
  cout << max_money << endl;

  return 0;
}

Error: TLE

Fixed submission:

#include <algorithm>
#include <bitset>
#include <chrono>
#include <cmath>
#include <cstdint>
#include <functional>
#include <iomanip>
#include <iostream>
#include <iterator>
#include <list>
#include <map>
#include <numeric>
#include <queue>
#include <random>
#include <set>
#include <sstream>
#include <stack>
#include <string>
#include <vector>

#define N_TIMES(i, n) for (uint64_t i = 0; i < n; ++i)
#define N_TIMES_REV(i, n) for (int64_t i = n - 1; i >= 0; --i)

template <typename T>
using maximum_heap = std::priority_queue<T, std::vector<T>, std::less<T>>;
template <typename T>
using minimum_heap = std::priority_queue<T, std::vector<T>, std::greater<T>>;

template <typename T>
std::istream &operator>>(std::istream &is, std::vector<T> &v) {
  for (typename std::vector<T>::size_type i = 0; i < v.size(); ++i) {
    is >> v[i];
  }
  return is;
}

using namespace std;

struct DPItem {
  uint64_t money, stock, price;
  DPItem(uint64_t money, uint64_t stock, uint64_t price)
      : money(money), stock(stock), price(price) {}
  uint64_t operator()() const { return money + stock * price; }
  bool operator<(const DPItem &rhs) const { return (*this)() < rhs(); }
  bool operator>(const DPItem &rhs) const { return (*this)() > rhs(); }
};

const uint64_t M = 1e+6;

int main() {
  uint64_t N;
  cin >> N;

  vector<uint64_t> A(N);
  cin >> A;

  vector<maximum_heap<DPItem>> dp(N + 1);
  dp[0].emplace(1000, 0, 0);
  N_TIMES(n, N) {
    uint64_t cnt = 0;
    while (!dp[n].empty() && cnt < M) {
      DPItem item = dp[n].top();
      dp[n].pop();
      // 何もしない
      dp[n + 1].push(item);
      ++cnt;

      // 全株売却
      if (item.stock > 0 && item.price < A[n]) {
        if ((n == N - 1) || (n < N - 1 && A[n] > A[n + 1])) {
          dp[n + 1].emplace(item.money + item.stock * A[n], 0, 0);
          ++cnt;
        }
      }

      // 最大購入
      uint64_t c = item.money / A[n];
      if (item.stock == 0 && c > 0) {
        if ((n == N - 1) || (n < N - 1 && A[n] < A[n + 1])) {
          dp[n + 1].emplace(item.money % A[n], item.stock + c, A[n]);
          ++cnt;
        }
      }
    }
  }

  uint64_t max_money = 0;
  while (!dp[N].empty()) {
    DPItem item = dp[N].top();
    dp[N].pop();
    max_money = max(max_money, item());
  }
  cout << max_money << endl;

  return 0;
}