Problem Description
Given an array nums of length n, you start at index 0 and need to reach index n-1 by only jumping to indices greater than your current one. The score for a jump from index i to j is defined as (j - i) * nums[i]. The objective is to calculate the maximum possible total score you can accumulate by the time you reach the last index.
Key Insights
- The problem is solved using dynamic programming where dp[j] represents the maximum score to reach index j.
- Transition: dp[j] = max(for each i < j){ dp[i] + (j - i) * nums[i] }.
- Rearranging the formula leads to dp[j] = max(for each i < j){ (dp[i] - i * nums[i]) + j * nums[i] }.
- This formulation is similar to a "line query" where each jump corresponds to a line function f(x) = mx + b, with m = nums[i] and b = dp[i] - inums[i].
- Using a Li-Chao Tree (or dynamic convex hull trick) efficiently supports adding such lines and querying maximum values in O(log(max_range)) per operation.
- The x-values (indices j) are increasing, but the slopes (nums[i]) are arbitrary; hence, the Li-Chao Tree is preferred.
Space and Time Complexity
Time Complexity: O(n * log(max_index)) where max_index is bounded by the number of indices (roughly 1e5).
Space Complexity: O(n) for storing dp values and the lines (nodes) in the Li-Chao Tree.
Solution
We use dynamic programming with a Li-Chao Tree to optimize the state transition. We define a function for each index i as f(x) = nums[i] * x + (dp[i] - i * nums[i]). For a given index j, dp[j] is computed as the maximum value among f(j) over all previously visited indices i (< j). We add these functions to our Li-Chao Tree as we iterate through the array and query the maximum for each j. This method avoids the O(n^2) approach and makes it feasible for large input sizes.