1696. 跳跃游戏 VI()

题目描述

每次可以最多跳k步,最终落点是n-1。得分定义为路径上的nums[i]之和,问最大得分?

f1-动态规划+单调队列

基本分析

  • 怎么跳可以取到最大?考虑跳到j点的最大值是f[j], 必须从满足j-i<=k的点i转移过来,问题就是在满足要求的区间内,怎么取到最大的f[i]?单调队列
  • 队头舍去什么?不满足下标约束的点
  • 怎么转移?队头得分+nums[j]
  • 队尾怎么去冗余?比j靠前且f[i]>=f[j]的点

代码

class Solution:
    def maxResult(self, nums: List[int], k: int) -> int:
        n = len(nums)
        f = [-inf] * n
        f[0] = nums[0]

        q = deque([0])

        for i in range(1, n):
            if q and i - q[0] > k:
                q.popleft()
            f[i] = f[q[0]] + nums[i]
            while q and f[q[-1]] <= f[i]:
                q.pop()
            q.append(i)
        
        return f[n-1]

总结

  • 典型的单调队列优化的dp题目
  • 给起点赋初值,从下个点开始遍历
————————

题目描述

每次可以最多跳k步,最终落点是n-1。得分定义为路径上的nums[i]之和,问最大得分?

f1-动态规划+单调队列

基本分析

  • 怎么跳可以取到最大?考虑跳到j点的最大值是f[j], 必须从满足j-i<=k的点i转移过来,问题就是在满足要求的区间内,怎么取到最大的f[i]?单调队列
  • 队头舍去什么?不满足下标约束的点
  • 怎么转移?队头得分+nums[j]
  • 队尾怎么去冗余?比j靠前且f[i]>=f[j]的点

代码

class Solution:
    def maxResult(self, nums: List[int], k: int) -> int:
        n = len(nums)
        f = [-inf] * n
        f[0] = nums[0]

        q = deque([0])

        for i in range(1, n):
            if q and i - q[0] > k:
                q.popleft()
            f[i] = f[q[0]] + nums[i]
            while q and f[q[-1]] <= f[i]:
                q.pop()
            q.append(i)
        
        return f[n-1]

总结

  • 典型的单调队列优化的dp题目
  • 给起点赋初值,从下个点开始遍历