2355. Maximum Number of Books You Can Take π
DifficultyHard
Description
You are given a 0-indexed integer array books of length n where books[i] denotes the number of books on the ith shelf of a bookshelf.
You are going to take books from a contiguous section of the bookshelf spanning from l to r where 0 <= l <= r < n. For each index i in the range l <= i < r, you must take strictly fewer books from shelf i than shelf i + 1.
Return the maximum number of books you can take from the bookshelf.
Example 1:
Input: books = [8,5,2,7,9] Output: 19 Explanation: - Take 1 book from shelf 1. - Take 2 books from shelf 2. - Take 7 books from shelf 3. - Take 9 books from shelf 4. You have taken 19 books, so return 19. It can be proven that 19 is the maximum number of books you can take.
Example 2:
Input: books = [7,0,3,4,5] Output: 12 Explanation: - Take 3 books from shelf 2. - Take 4 books from shelf 3. - Take 5 books from shelf 4. You have taken 12 books so return 12. It can be proven that 12 is the maximum number of books you can take.
Example 3:
Input: books = [8,2,3,7,3,4,0,1,4,3] Output: 13 Explanation: - Take 1 book from shelf 0. - Take 2 books from shelf 1. - Take 3 books from shelf 2. - Take 7 books from shelf 3. You have taken 13 books so return 13. It can be proven that 13 is the maximum number of books you can take.
Constraints:
1 <= books.length <= 1050 <= books[i] <= 105
Solutions
Solution 1: Monotonic Stack + Dynamic Programming
Thinking
Books come from a contiguous range of shelves, decreasing by at least one toward the left. Finding the break by brute force for every right end is too slow.
Let \(nums[i]=books[i]-i\). The break is the nearest smaller \(nums[j]\) on the left. A monotonic stack fills \(left[i]\); \(dp[i]\) is the best take ending at \(i\): an arithmetic segment in the middle plus \(dp[j]\) on the left.
Let \(dp[i]\) be the maximum number of books taken from a contiguous segment that ends at shelf \(i\). Set \(nums[i] = books[i] - i\). If the strictly decreasing pattern breaks at some \(j\) with \(0 \le j < i\), then \(books[j] < books[i] - (i - j)\), that is \(nums[j] < nums[i]\). A monotonic stack finds, for each index, the nearest strictly smaller \(nums\) on the left and stores it as \(j\). When no such index exists, \(j = -1\).
The books taken from shelf \(j + 1\) through \(i\) form an arithmetic sequence with difference \(1\). Its length is \(cnt = \min(books[i], i - j)\), it ends at \(books[i]\), and it starts at \(u = books[i] - cnt + 1\). The sum of that sequence is \(s = (u + books[i]) \times cnt / 2\). Then \(dp[i] = s\), plus \(dp[j]\) when \(j \ne -1\).
The answer is \(\max\limits_{i} dp[i]\).
The time complexity is \(O(n)\), and the space complexity is \(O(n)\), where \(n\) is the length of \(books\).
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 | |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 | |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 | |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 | |