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 themaximum number of books you can take from the bookshelf.
Input: books =[8,5,2,7,9]Output: 19Explanation:
- 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 return19.It can be proven that 19is the maximum number of books you can take.
Example 2:
1
2
3
4
5
6
7
8
Input: books =[7,0,3,4,5]Output: 12Explanation:
- Take 3 books from shelf 2.- Take 4 books from shelf 3.- Take 5 books from shelf 4.You have taken 12 books so return12.It can be proven that 12is the maximum number of books you can take.
Example 3:
1
2
3
4
5
6
7
8
9
Input: books =[8,2,3,7,3,4,0,1,4,3]Output: 13Explanation:
- 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 return13.It can be proven that 13is the maximum number of books you can take.
We want to take books from a contiguous segment such that for every shelf, the number of books taken is strictly less than the next shelf. The optimal way is to find, for each position, the best segment ending at that position using a stack to maintain the strictly increasing property efficiently.
classSolution {
public:longlong maximumBooks(vector<int>& books) {
int n = books.size();
vector<longlong> dp(n);
stack<int> st;
longlong ans =0;
for (int i =0; i < n; ++i) {
while (!st.empty() && books[st.top()] >= books[i] - (i - st.top())) st.pop();
int len = st.empty() ? i +1: i - st.top();
longlong first = books[i] - len +1;
if (first <0) first =0;
longlong sum = (first + books[i]) * len /2;
dp[i] = sum + (st.empty() ?0: dp[st.top()]);
ans = max(ans, dp[i]);
st.push(i);
}
return ans;
}
};
classSolution {
publiclongmaximumBooks(int[] books) {
int n = books.length;
long[] dp =newlong[n];
Deque<Integer> st =new ArrayDeque<>();
long ans = 0;
for (int i = 0; i < n; i++) {
while (!st.isEmpty() && books[st.peek()]>= books[i]- (i - st.peek())) st.pop();
int len = st.isEmpty() ? i + 1 : i - st.peek();
long first = books[i]- len + 1;
if (first < 0) first = 0;
long sum = (first + books[i]) * len / 2;
dp[i]= sum + (st.isEmpty() ? 0 : dp[st.peek()]);
ans = Math.max(ans, dp[i]);
st.push(i);
}
return ans;
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
classSolution {
funmaximumBooks(books: IntArray): Long {
val n = books.size
val dp = LongArray(n)
val st = ArrayDeque<Int>()
var ans = 0Lfor (i in0 until n) {
while (st.isNotEmpty() && books[st.last()] >= books[i] - (i - st.last())) st.removeLast()
val len = if (st.isEmpty()) i + 1else i - st.last()
var first = books[i] - len + 1if (first < 0) first = 0val sum = (first + books[i]).toLong() * len / 2 dp[i] = sum + if (st.isEmpty()) 0else dp[st.last()]
ans = maxOf(ans, dp[i])
st.addLast(i)
}
return ans
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
classSolution:
defmaximumBooks(self, books: list[int]) -> int:
n = len(books)
dp = [0] * n
st = []
ans =0for i in range(n):
while st and books[st[-1]] >= books[i] - (i - st[-1]):
st.pop()
length = i +1ifnot st else i - st[-1]
first = books[i] - length +1if first <0:
first =0 total = (first + books[i]) * length //2 dp[i] = total + (0ifnot st else dp[st[-1]])
ans = max(ans, dp[i])
st.append(i)
return ans
impl Solution {
pubfnmaximum_books(books: Vec<i32>) -> i64 {
let n = books.len();
letmut dp =vec![0i64; n];
letmut st = Vec::new();
letmut ans =0i64;
for i in0..n {
whilelet Some(&last) = st.last() {
if books[last] >= books[i] - (i asi32- last asi32) {
st.pop();
} else {
break;
}
}
let len =if st.is_empty() { i +1 } else { i - st.last().unwrap() };
letmut first = books[i] - len asi32+1;
if first <0 { first =0; }
let sum = (first + books[i]) asi64* len asi64/2;
dp[i] = sum +if st.is_empty() { 0 } else { dp[*st.last().unwrap()] };
ans = ans.max(dp[i]);
st.push(i);
}
ans
}
}