问题描述
小R正在研究一组观光景点,每个景点都有一个评分,保存在数组values中,其中values[i]表示第i个观光景点的评分。同时,景点之间的距离由它们的下标差j-i表示。一对景点(i<j)的观光组合得分为values[i] + values[j] + i - j,也就是两者评分之和减去它们之间的距离。小R想知道,在哪种情况下能够获得观光景点组合的最高得分。
测试样例
样例1:
输入:
values = [8, 3, 5, 5, 6]输出:11
样例2:
输入:
values = [10, 4, 8, 7]输出:16
样例3:
输入:
values = [1, 2, 3, 4,5]输出:8
思路1:
- 遍历所有可能的景点组合。
- 对于给定的数组
values,它的长度为n。 - 我们需要遍历所有满足
i < j的组合。 - 计算每个组合的得分
values[i]+values[j]+i - j。 - 然后找到其中的最大值。
- 这种方法的时间复杂度是O(n2) ,因为对于长度为
n的数组,我们需要计算大约n(n−1)/2 个组合的得分。
思路2:
- 我们可以对得分公式
values[i]+values[j]+i - j进行变形,得到(values[i]+i)+(values[j]-j)。 - 我们可以先计算一个辅助数组
newValues,其中newValues[i]=values[i]+i。 - 然后,对于每个
j,我们要找到newValues中i < j时的最大值,计算max(newValues[i])+(values[j]-j)。 - 这样,我们可以通过一次遍历数组
values来计算每个位置的最大得分,时间复杂度可以优化到O(n)
代码实现(思路1):
def solution(values: list) -> int:
max=0
reluslt=0
for i in range(len(values)):
for j in range(i+1 , len(values)):
reluslt=values[i]+values[j]+i-j
if reluslt>max:
max=reluslt
return max
if __name__ == '__main__':
print(solution(values=[8, 3, 5, 5, 6]))
print(solution(values=[10, 4, 8, 7]))
print(solution(values=[1, 2, 3, 4, 5]))
代码实现(思路2):
def solution(values):
n = len(values)
newValues = [values[i]+i for i in range(n)]
maxScore = 0
preMax = newValues[0]
for j in range(1, n):
maxScore = max(maxScore, preMax+(values[j]-j))
preMax = max(preMax, newValues[j])
return maxScore
if __name__ == '__main__':
print(solution(values=[8, 3, 5, 5, 6]))
print(solution(values=[10, 4, 8, 7]))
print(solution(values=[1, 2, 3, 4, 5]))
总结
-
公式变形的重要性
- 在解决这类观光景点组合得分问题时,对原始得分公式进行合理变形是关键步骤。通过将
values[i]+values[j]+i - j变形为(values[i]+i)+(values[j]-j),能够将问题转化为更容易处理的形式。这种变形使得我们可以分别考虑两个部分的最大值,从而简化了计算过程。
- 在解决这类观光景点组合得分问题时,对原始得分公式进行合理变形是关键步骤。通过将
-
辅助数组的运用
- 构建辅助数组(如
newValues)是优化算法的有效手段。辅助数组能够存储经过部分计算后的结果,减少了重复计算。在这个例子中,newValues存储了values[i]+i的值,使得后续计算每个组合得分时,能够快速获取到需要的部分最大值。
- 构建辅助数组(如
-
时间复杂度优化
- 从暴力解法的O(n2)
时间复杂度优化到O(n)
是算法优化的显著成果。暴力解法需要遍历所有可能的景点组合,计算量随着景点数量的增加呈二次方增长。而优化后的算法通过一次遍历数组就能得到结果,大大提高了算法的效率,尤其在处理大规模数据时优势明显。
- 从暴力解法的O(n2)
思维延伸
-
多条件组合优化
- 如果在观光景点的评分和距离计算中加入更多的条件,例如不同时间段景点评分有波动(可以用一个与时间相关的函数来表示评分的变化),或者景点之间的距离计算需要考虑地形因素(如爬坡、过河等特殊情况会增加距离的计算权重)。此时,我们需要对公式进行更复杂的变形,并且可能需要构建多个辅助数组来分别处理不同的条件,然后再综合考虑这些因素来计算最优组合。
-
动态规划思想的拓展
- 这种问题可以看作是一种特殊的动态规划问题。我们可以进一步思考如何将动态规划的思想更深入地应用到类似问题中。例如,当景点之间存在相互影响关系时(比如某个景点的评分会受到之前参观景点数量或者顺序的影响),我们可以通过建立状态转移方程来求解最优解。状态可以定义为已经参观的景点数量、当前的总得分等,然后根据不同的状态转移规则来计算最终的最优观光组合。