Input: nums =[1,5,8]Output: 16Explanation:
There are two possible ways to reach the last element:*`0 -> 1 -> 2`with a score of `(1 - 0) * 5 + (2 - 1) * 8 = 13`.*`0 -> 2`with a score of `(2 - 0) * 8 = 16`.
Example 2:
1
2
3
4
5
Input: nums =[4,5,2,8,9,1,3]Output: 42Explanation:
We can do the hopping `0 -> 4 -> 6`with a score of `(4 - 0) * 9 + (6 - 4) * 3
= 42`.
This is a variant of the first hopping problem, but we want to optimize the O(n^2) DP. Since the score for hopping from i to j is (j-i)*nums[j] + dp[j], and nums[j] is the only variable, we can use a monotonic stack to keep track of the best future hops efficiently.
classSolution {
public:int maxScore(vector<int>& nums) {
int n = nums.size();
vector<int> dp(n, 0);
vector<int> st;
dp[n-1] =0;
st.push_back(n-1);
for (int i = n-2; i >=0; --i) {
int best =0;
for (int j : st) {
best = max(best, (j-i)*nums[j] + dp[j]);
}
dp[i] = best;
while (!st.empty() && nums[i] >= nums[st.back()]) st.pop_back();
st.push_back(i);
}
return dp[0];
}
};
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
funcmaxScore(nums []int) int {
n:= len(nums)
dp:= make([]int, n)
st:= []int{n-1}
fori:=n-2; i>=0; i-- {
best:=0for_, j:=rangest {
ifv:= (j-i)*nums[j]+dp[j]; v > best {
best = v }
}
dp[i] = bestfor len(st) > 0&&nums[i] >=nums[st[len(st)-1]] {
st = st[:len(st)-1]
}
st = append(st, i)
}
returndp[0]
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
classSolution {
publicintmaxScore(int[] nums) {
int n = nums.length;
int[] dp =newint[n];
Deque<Integer> st =new ArrayDeque<>();
st.push(n-1);
for (int i = n-2; i >= 0; --i) {
int best = 0;
for (int j : st) {
best = Math.max(best, (j-i)*nums[j]+ dp[j]);
}
dp[i]= best;
while (!st.isEmpty() && nums[i]>= nums[st.peek()]) st.pop();
st.push(i);
}
return dp[0];
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
classSolution {
funmaxScore(nums: IntArray): Int {
val n = nums.size
val dp = IntArray(n)
val st = ArrayDeque<Int>()
st.addLast(n-1)
for (i in n-2 downTo 0) {
var best = 0for (j in st) {
best = maxOf(best, (j-i)*nums[j] + dp[j])
}
dp[i] = best
while (st.isNotEmpty() && nums[i] >= nums[st.last()]) st.removeLast()
st.addLast(i)
}
return dp[0]
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
classSolution:
defmaxScore(self, nums: list[int]) -> int:
n = len(nums)
dp = [0]*n
st = [n-1]
for i in range(n-2, -1, -1):
best =0for j in st:
best = max(best, (j-i)*nums[j] + dp[j])
dp[i] = best
while st and nums[i] >= nums[st[-1]]:
st.pop()
st.append(i)
return dp[0]