Table of Contents
Problem
You are given an array books
where books[i] = [thicknessi, heighti]
indicates the thickness and height of the ith
book. You are also given an integer shelfWidth
.
We want to place these books in order onto bookcase shelves that have a total width shelfWidth
.
We choose some of the books to place on this shelf such that the sum of their thickness is less than or equal to shelfWidth
, then build another level of the shelf of the bookcase so that the total height of the bookcase has increased by the maximum height of the books we just put down. We repeat this process until there are no more books to place.
Note that at each step of the above process, the order of the books we place is the same order as the given sequence of books.
- For example, if we have an ordered list of
5
books, we might place the first and second book onto the first shelf, the third book on the second shelf, and the fourth and fifth book on the last shelf.
Return the minimum possible height that the total bookshelf can be after placing shelves in this manner.
Example 1:
Input: books = [[1,1],[2,3],[2,3],[1,1],[1,1],[1,1],[1,2]], shelfWidth = 4 Output: 6 Explanation: The sum of the heights of the 3 shelves is 1 + 3 + 2 = 6. Notice that book number 2 does not have to be on the first shelf.
Example 2:
Input: books = [[1,3],[2,4],[3,2]], shelfWidth = 6 Output: 4
Constraints:
1 <= books.length <= 1000
1 <= thicknessi <= shelfWidth <= 1000
1 <= heighti <= 1000
Solution
此題要求解的是,在將所有的書放進書櫃後,計算出最小可能的書櫃高度。每一層可以放一本或多本書,只要總書寬不要超過 shelfWidth
。題目中有一個很重要的限制就是,所有的書必須要依照它們原有的順序放入書櫃中。這個限制縮減了可能擺放的組合。
解題的構想是,我們在第一層放書本 1,剩餘書本 2 ~ 7 從下一層開始擺放。或是,我們在第一層放書本 1 ~ 2,剩餘書本 3 ~ 7 從下一層開始擺放。我們無法再擺放書本 3,因為那會超過 shelfWidth
。然後,比較第一種與第二種擺放方式的高度,取最小的就是答案。
在上述的構想中,我們沒有去解釋如何計算剩餘書本最終的擺放高度。因為在擺放剩餘書本時,也是依照上述的構想遞迴地擺放下去。
Dynamic Programming
class Solution { public int minHeightShelves(int[][] books, int shelfWidth) { return minHeightShelves(books, shelfWidth, 0, new int[books.length]); } private int minHeightShelves(int[][] books, int shelfWidth, int index, int[] dp) { if (index >= books.length) return 0; if (dp[index] != 0) return dp[index]; int minHeight = Integer.MAX_VALUE; int height = 0; int width = 0; for (int i = index; i < books.length; i++) { width += books[i][0]; if (width > shelfWidth) break; height = Math.max(height, books[i][1]); minHeight = Math.min(minHeight, height + minHeightShelves(books, shelfWidth, i + 1, dp)); } dp[index] = minHeight; return minHeight; } }
參考
- 1105. Filling Bookcase Shelves, LeetCode.
- 1105. Filling Bookcase Shelves, LeetCode Solutions.