LeetCode 1014. 最佳观光组合
给定正整数数组 A,A[i] 表示第 i 个观光景点的评分,并且两个景点 i 和 j 之间的距离为 j - i。
一对景点(i < j)
组成的观光组合的得分为(A[i] + A[j] + i - j)
:景点的评分之和减去它们两者之间的距离。
返回一对观光景点能取得的最高分。
示例:
输入:[8,1,5,2,6]
输出:11
解释:i = 0, j = 2, A[i] + A[j] + i - j = 8 + 5 + 0 - 2 = 11
思路:
咋一看,很简单,代码撸完,超时
可以重新组合得分公式:(A[i] + i )+ (A[j] - j)
这样就可以看成是左A[i]+i和右A[j]-j两部分和的最大值。这里A[i] + i 和 A[j] - j 相互独立
考虑约束条件i < j
,于是形成动态规划的思路:
- 遍历A数组,求每个j下的A[j] - j的值,
- 再求i < j 下的max(A[i] + i)
- 最后再求所有遍历过程中的最大值就好了。
好了,看代码
def maxScoreSightseeingPair(self, A: List[int]) -> int:
# 暴力超时解法
# n = len(A)
# score = -float('inf')
# for i in range(n - 1):
# for j in range(i + 1, n):
# score = max(score, A[i] + A[j] + i - j)
# return score
# A[i]+i+A[j]-j
left = A[0] + 0 # left初始化为第一个
res = -1
for j in range(1, len(A)): # 从第二个开始遍历
right = A[j] - j # 先更新右边right
res = max(res, left + right) # 更新当前最大值
i = j # left 后移一位
left = max(left, A[i] + i) # 再更新左边left
return res