队列优化dp || 线段树优化dp
前言:这个题目就是一个很经典的dp问题,之前做过类似的跳格子,这个题目如果用暴力的dp,那么复杂度就是 n ∗ k n*k n∗k 这个肯定是会超时的
题目链接
class Solution:def maxResult(self, nums: List[int], k: int) -> int:# 这个不就是一个dp,但是怎么能降低复杂度呢n = len(nums)dp = [-inf]*(n)dp[0] = nums[0]for i in range(n):for j in range(i+1,min(i+k+1,n)):dp[j] = max(dp[j],dp[i]+nums[j])# print(i,dp[i])return dp[-1]
如果我们用线段树来优化查询的话
class Tree:def __init__(self,n):self.t = [-inf]*(4*n)def update(self,o,l,r,index,va):if l==r:self.t[o] = vareturnmid = (l+r)//2if mid>=index:self.update(o*2,l,mid,index,va)else:self.update(o*2+1,mid+1,r,index,va)self.t[o] = max(self.t[o*2],self.t[o*2+1])def query(self,o,l,r,L,R):if L<=l and r<=R:return self.t[o]tmp = -infmid = (l+r)//2if mid>=L:tmp = max(tmp,self.query(o*2,l,mid,L,R))if mid<R:tmp = max(tmp,self.query(o*2+1,mid+1,r,L,R))return tmpclass Solution:def maxResult(self, nums: List[int], k: int) -> int:# 这个不就是一个dp,但是怎么能降低复杂度呢n = len(nums)dp = [-inf]*(n)dp[0] = nums[0]a = Tree(n)a.update(1,0,n-1,0,dp[0])for i in range(1,n):pre = a.query(1,0,n-1,max(0,i-k),i-1)dp[i] = pre + nums[i]a.update(1,0,n-1,i,dp[i])return dp[-1]
队列优化
class Solution:def maxResult(self, nums: List[int], k: int) -> int:n = len(nums)f = [0] * nf[0] = nums[0]q = deque([0])for i in range(1, n):# 1. 出if q[0] < i - k:q.popleft()# 2. 转移f[i] = f[q[0]] + nums[i]# 3. 入while q and f[i] >= f[q[-1]]:q.pop()q.append(i)return f[-1]
这个有点难以理解