Suppose you want to read a book with $n$ chapters, and chapter $i$ has $a_i$ pages. Now you want to read the entire book in $d$ days. But there are two restrictions:

  • by the end of each day, you cannot be in the middle of a chapter.
  • You must read the chapters in order.

You also want to minimize the maximum number of pages read in a single day.

Now let's consider the brute force algorithm: look at every possible way of dividing the chapters into $d$ days, and compute the maximum number of pages read in a single day. There are $\binom{n+d-1}{n}$ ways to divide the chapters up (using stars and bars) and you must check the number of pages read in each day, ultimately by doing $n$ operations. So this algorithm takes $O\left(n\binom{n+d-1}n\right)$ time, which is pretty bad, but I can't think of how to improve it.

Imagine an analogous decision problem:

Given a book with $n$ chapters, is it possible to read it in $d$ days such that you never read more than $k$ pages in a single day without violating the restrictions?

The decision problem seems to have a really easy greedy solution: Each day, read as many chapters as you can without exceeding $k$ pages. If you're done with the book after $d$ days, the answer is yes. Otherwise, the answer is no. This takes $O(n)$ time.

It seems weird that the decision problem would have such a simple solution but the original one doesn't. Can anyone think of how to do better than the brute force algorithm for the original problem?


Your brute force solution is far from optimal. One improvement is to use dynamic programming. For every $i,j$, determine the minimal maximum number of pages per day when reading the first $i$ chapters in $j$ days. Implemented naively, this leads to an $O(n^2d)$ solution, though you might be able to improve this to $O(nd)$ using a smart implementation.

A perhaps better solution is to use binary search. You state that it is easy to determine whether a certain maximum number of pages can be achieved. To find the minimum number that can be achieved, use binary search with the decision algorithm as an oracle. The running time in principle depends on the total number of pages, but in fact there are only $n^2$ different possible answers, and this leads to an $O(n^2)$ algorithm, which can probably be improved to $O(n\log n)$ with some additional ideas.

| cite | improve this answer | |
  • $\begingroup$ Thanks. I see how I could get it to $O(n^2)$ but what additional ideas do you think could get it down to $O(n\log n) $? $\endgroup$ – Riley Oct 14 '17 at 22:40
  • $\begingroup$ If I knew them, I would write them. $\endgroup$ – Yuval Filmus Oct 14 '17 at 22:42

If you have a limit of k pages per day, then you can easily check whether you can read the book in d days using the greedy reading strategy.

Let T be the total number of pages. When d = 1, k = T is obviously the best solution, so assume d ≥ 2. Let C be the number of pages in the longest chapter.

A lower bound for k is max (C, ceil (T / d)). Let d' = floor (d / 2), then an upper bound is max (C, ceil (T / d')): That is because in any two consecutive days, we will be reading more than k pages, or we could have read those pages in one day. There are d' pairs of consecutive days, so we can read more than k * d' pages in 2d' days, therefore T pages in d days.

If C ≥ ceil (T / d') then k = C is the smallest possible value for k. Otherwise, since checking whether k is large enough or not takes O (n), binary search will find the smallest possible k in O (n log (T / d')) = O (n log (T / d)) operations.

A small improvement: During the binary search, if the greedy algorithm determines that reading up to k pages per day works, you can check what the largest number k' of pages read in one day actually was, and obviously choosing k' instead of k will also work. If reading up to k pages per day didn't work, you can determine the smallest k' where you could have read more pages on one day, and use k' as a lower bound. This should help if T is excessively large.

PS. You can probably a better execution time on average. Checking whether k pages per day is enough can be done in O (n) where n is the number of chapters. But if k' is close to k, and n is significantly larger than d, then we should be able to check k' by modifying the result of the greedy algorithm for k in time that is closer to d than to n.

| cite | improve this answer | |
  • $\begingroup$ This is mentioned in my answer. What if T is very large? $\endgroup$ – Yuval Filmus Oct 14 '17 at 22:43

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.