你给出的题目是
https://www.bing.com/search?form=SKPBOT&q=2355.%20Maximum%20Number%20of%20Books%20You%20Can%20Take ,这是一个动态规划和单调栈的结合问题。动态规划的思路是,对于每个位置 i ,我们维护一个 dp[i] 表示以 i 为右端点的区间能取到的最大书籍数。我们可以用一个单调栈来维护一个递减的序列,当我们遇到一个比栈顶元素小的数时,我们就找到了一个合法的区间,然后更新 dp[i] 为 dp[j] + (i - j) * books[i] ,其中 j 是栈顶元素的下标。这样我们就可以在 O(n) 的时间内求出所有的 dp[i] ,然后取最大值即可。我用 C++ 写了一段代码,你可以参考一下:
#include <iostream>
#include <vector>
#include <stack>
using namespace std;
int maxBooks(vector<int>& books, int l, int r) {
int n = books.size();
vector<int> dp(n + 1, 0); // dp[i] means the max books we can take from [0, i]
stack<int> st; // a monotonic decreasing stack
st.push(0); // a dummy element
int ans = 0;
for (int i = 1; i <= n; i++) {
while (!st.empty() && books[
st.top()] > books[i]) {
// we find a valid interval [j + 1, i]
int j =
st.top();
st.pop();
dp[i] = max(dp[i], dp[j] + (i - j) * books[i]);
}
st.push(i);
if (i >= l && i <= r) {
// update the answer if i is in the range
ans = max(ans, dp[i]);
}
}
return ans;
}
int main() {
vector<int> books = {8, 5, 2, 7, 9};
int l = 1, r = 4;
cout << maxBooks(books, l, r) << endl; // output: 19
return 0;
}