3205. Maximum Array Hopping Score I π
Description
Given an array nums, you have to get the maximum score starting from index 0 and hopping until you reach the last element of the array.
In each hop, you can jump from index i to an index j > i, and you get a score of (j - i) * nums[j].
Return the maximum score you can get.
Example 1:
Input: nums = [1,5,8]
Output: 16
Explanation:
There are two possible ways to reach the last element:
0 -> 1 -> 2with a score of(1 - 0) * 5 + (2 - 1) * 8 = 13.0 -> 2with a score of(2 - 0) * 8 = 16.
Example 2:
Input: nums = [4,5,2,8,9,1,3]
Output: 42
Explanation:
We can do the hopping 0 -> 4 -> 6 with a score of (4 - 0) * 9 + (6 - 4) * 3 = 42.
Constraints:
2 <= nums.length <= 1031 <= nums[i] <= 105
Solutions
Solution 1: Memoization Search
Thinking
From index \(0\) we jump right to some \(j\) and score \((j-i)\times\textit{nums}[j]\), maximizing the total. \(n\le 10^3\) forbids enumerating jump sequences exponentially, yet \(O(n^2)\) states fit the limit.
The subproblem depends only on the start \(i\): once we are at \(i\), the best continuation does not depend on how we arrived. Define \(\textit{dfs}(i)\) as the best score from \(i\), take the max of \((j-i)\times\textit{nums}[j]+\textit{dfs}(j)\) over \(j>i\), and memoize.
We design a function \(\textit{dfs}(i)\), which represents the maximum score that can be obtained starting from index \(i\). Therefore, the answer is \(\textit{dfs}(0)\).
The execution process of the function \(\textit{dfs}(i)\) is as follows:
We enumerate the next jump position \(j\). Thus, the score that can be obtained starting from index \(i\) is \((j - i) \times \textit{nums}[j]\), plus the maximum score that can be obtained starting from index \(j\), making the total score \((j - i) \times \textit{nums}[j] + \textit{dfs}(j)\). We enumerate all possible \(j\) and take the maximum score.
To avoid redundant calculations, we use memoization search. We save the calculated value of \(\textit{dfs}(i)\), so it can be directly returned next time.
The time complexity is \(O(n^2)\), and the space complexity is \(O(n)\). Here, \(n\) is the length of the array.
1 2 3 4 5 6 7 8 9 | |
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 | |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 | |
Solution 2: Dynamic Programming
Thinking
The recurrence in Solution 1 is already optimal; the recursion stack and cache are unnecessary. The same transfer becomes bottom-up: \(f[j]\) is the best score from \(0\) to \(j\), and each \(j\) enumerates predecessors \(i<j\). The time is still \(O(n^2)\), now iterative.
We can transform the memoization search from Solution 1 into dynamic programming.
Define \(f[j]\) as the maximum score that can be obtained starting from index \(0\) and ending at index \(j\). Therefore, the answer is \(f[n - 1]\).
The state transition equation is:
The time complexity is \(O(n^2)\), and the space complexity is \(O(n)\). Here, \(n\) is the length of the array.
1 2 3 4 5 6 7 8 | |
1 2 3 4 5 6 7 8 9 10 11 12 | |
1 2 3 4 5 6 7 8 9 10 11 12 13 | |
1 2 3 4 5 6 7 8 9 10 | |
1 2 3 4 5 6 7 8 9 10 | |
Solution 3: Monotonic Stack
Thinking
Solution 2 is still quadratic. From \(i\), jumping to a \(j\) that is not the next value no smaller than the current one cannot beat inserting that intermediate hop, so the optimal path only visits the monotone sequence of next-greater indices. A monotonic stack extracts that index list; scoring adjacent hops is then linear.
We observe that for the current position \(i\), we should jump to the next position \(j\) with the maximum value to obtain the maximum score.
Therefore, we traverse the array \(\textit{nums}\), maintaining a stack \(\textit{stk}\) that is monotonically decreasing from the bottom to the top of the stack. For the current position \(i\) being traversed, if the value corresponding to the top element of the stack is less than or equal to \(\textit{nums}[i]\), we continuously pop the top element of the stack until the stack is empty or the value corresponding to the top element of the stack is greater than \(\textit{nums}[i]\), and then push \(i\) into the stack.
Next, we initialize the answer \(\textit{ans}\) and the current position \(i = 0\), traverse the elements in the stack, each time taking out the top element \(j\), updating the answer \(\textit{ans} += \textit{nums}[j] \times (j - i)\), and then updating \(i = j\).
Finally, return the answer \(\textit{ans}\).
The time complexity is \(O(n)\), and the space complexity is \(O(n)\). Here, \(n\) is the length of the array.
1 2 3 4 5 6 7 8 9 10 11 12 | |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 | |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 | |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 | |