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

#include <bits/stdc++.h>

#ifdef LOCAL
#include "dump.hpp"
#else
#define dump(...)
#endif

using namespace std;

inline bool check(int w, int limit, const vector<int> &x,
                  const vector<int> &sum) {
  const int n = x.size();

  int mn_next = n;
  int mx_next = n;
  int cnt = 0;
  vector<bool> dp(n + 1, false);
  dp[n] = true;

  for (int i = n - 1; i >= 0; --i) {
    if (sum[n] - sum[i] + 1 * (mn_next - i - 1) <= w) {
      dp[i] = true;
      continue;
    }

    while (sum[mn_next - 1] - sum[i] + 1 * (mn_next - i - 2) > w) {
      if (dp[--mn_next])
        --cnt;
    }

    while (sum[mx_next - 1] - sum[i] + limit * (mx_next - i - 2) >= w) {
      if (dp[--mx_next])
        ++cnt;
    }

    if (cnt)
      dp[i] = true;
  }

  return dp[0];
}

int main() {
  cin.tie(nullptr);
  ios::sync_with_stdio(false);

  for (int w, n; cin >> w >> n && w;) {
    vector<int> x(n);
    for (auto &e : x)
      cin >> e;

    vector<int> sum(n + 1);
    partial_sum(begin(x), end(x), sum.begin() + 1);

    int L = 0, R = w;
    while (L + 1 < R) {
      const int M = (L + R) / 2;
      if (check(w, M, x, sum)) {
        R = M;
      } else {
        L = M;
      }
    }

    cout << R << endl;
  }

  return EXIT_SUCCESS;
}

Error: TLE

Fixed submission:

#include <algorithm>
#include <array>
#include <bitset>
#include <cassert>
#include <cctype>
#include <climits>
#include <cmath>
#include <complex>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <ctime>
#include <deque>
#include <functional>
#include <iostream>
#include <iterator>
#include <list>
#include <map>
#include <numeric>
#include <queue>
#include <random>
#include <set>
#include <sstream>
#include <stack>
#include <string>
#include <tuple>
#include <unordered_map>
#include <unordered_set>
#include <utility>
#include <vector>
using namespace std;

#define dump(a) (cerr << (#a) << " = " << (a) << endl)

template <class T> inline void chmax(T &a, const T &b) {
  if (b > a)
    a = b;
}
template <class T> inline void chmin(T &a, const T &b) {
  if (b < a)
    a = b;
}

template <typename T, typename U>
ostream &operator<<(ostream &os, const pair<T, U> &p) {
  os << '(' << p.first << ", " << p.second << ')';
  return os;
}

template <class Tuple, unsigned Index>
void print_tuple(ostream &os, const Tuple &t) {}

template <class Tuple, unsigned Index, class Type, class... Types>
void print_tuple(ostream &os, const Tuple &t) {
  if (Index > 0)
    os << ", ";
  os << get<Index>(t);
  print_tuple<Tuple, Index + 1, Types...>(os, t);
}

template <class... Types>
ostream &operator<<(ostream &os, const tuple<Types...> &t) {
  os << '(';
  print_tuple<tuple<Types...>, 0, Types...>(os, t);
  return os << ')';
}

template <class Iterator>
ostream &dump_range(ostream &, Iterator, const Iterator &);

template <typename T> ostream &operator<<(ostream &os, vector<T> c) {
  return dump_range(os, c.cbegin(), c.cend());
}

template <class Iterator>
ostream &dump_range(ostream &os, Iterator first, const Iterator &last) {
  os << '[';
  for (int i = 0; first != last; ++i, ++first) {
    if (i)
      os << ", ";
    os << *first;
  }
  return os << ']';
}

constexpr int INF = 0xfffffff;

int main() {
  cin.tie(0);
  ios::sync_with_stdio(false);

  for (int w, n; cin >> w >> n && w;) {
    vector<int> words(n);
    for (int i = 0; i < n; ++i) {
      cin >> words[i];
    }

    vector<int> sum(n + 1, 0);
    for (int i = 0; i < n; ++i) {
      sum[i + 1] = sum[i] + words[i];
    }

    vector<int> dp(n + 1, INF);
    dp[0] = 1;
    for (int i = 0; i < n; ++i) {
      for (int j = i + 2; j <= n; ++j) {
        const int rest = w - sum[j] + sum[i];
        const int num_space = j - i - 1;
        if (rest < num_space)
          break;

        chmin(dp[j], max<int>(dp[i], ceil((double)rest / num_space)));
      }

      const int rest = w - sum[n] + sum[i];
      const int num_space = n - i - 1;
      if (rest < num_space)
        continue;
      chmin(dp[n], dp[i]);
    }

    cout << dp[n] << endl;
  }

  return EXIT_SUCCESS;
}