青训营X豆包MarsCode 技术训练营心得体会| 豆包MarsCode AI 刷题

46 阅读3分钟

关于观光景点组合问题分析

问题描述

小R正在研究一组观光景点,每个景点都有一个评分,保存在数组 values 中,其中 values[i] 表示第 i 个观光景点的评分。同时,景点之间的距离由它们的下标差 j - i 表示。

一对景点 (i < j) 的观光组合得分为 values[i] + values[j] + i - j,也就是两者评分之和减去它们之间的距离。

小R想知道,在哪种情况下能够获得观光景点组合的最高得分。

思路

1. 暴力解法思路

双层循环遍历

-   使用两层嵌套的循环来遍历数组 `values`。外层循环控制第一个景点的下标 `i`,从数组的起始位置开始,逐步向后移动。内层循环控制第二个景点的下标 `j`,对于每个固定的 `i``j` 从 `i + 1` 开始,一直到数组的末尾。这样就能遍历所有可能的景点组合 `(i, j)` 且满足 `i < j`
  • 计算组合得分

    • 对于每一对景点组合 (i, j),根据给定的公式 values[i] + values[j] + i - j 来计算它们的观光组合得分。
  • 记录最高得分及对应组合

    • 初始化一个变量来记录当前找到的最高得分,初始值可以设为一个较小的值(比如负无穷)。同时,记录下对应的景点下标组合 (i, j)
    • 在每次计算完一个组合的得分后,将其与当前的最高得分进行比较。如果该得分大于最高得分,就更新最高得分以及对应的景点下标组合。

2. 优化解法思路(动态规划相关思路)

  • 分析公式特点

    • 对观光组合得分公式 values[i] + values[j] + i - j 进行变形,可以得到 (values[i] + i) + (values[j] - j)。这样就可以将问题转化为分别考虑 values[i] + i 和 values[j] - j 这两部分。
  • 预处理部分结果

    • 创建两个辅助数组,一个数组 leftMax 用来记录从左到右遍历数组时,每个位置 i 对应的 values[i] + i 的最大值;另一个数组 rightMax 用来记录从右到左遍历数组时,每个位置 j 对应的 values[j] - j 的最大值。
    • 通过一次遍历数组就能填充好 leftMax 数组,在遍历过程中不断更新当前位置及之前位置的最大值。同样,通过一次反向遍历数组就能填充好 rightMax 数组。
  • 寻找最高得分组合

    • 再次遍历数组(这次可以只遍历一次,利用前面预处理得到的两个辅助数组)。对于每个位置 i,此时可以通过 leftMax[i] 得到左边部分(values[i] + i)的最大值,通过 rightMax[i + 1] 得到右边部分(values[j] - j,这里 j > i)的最大值。将这两部分相加就能得到以 i 为分割点的一种可能的最高观光组合得分。

    • 在遍历过程中,不断比较并更新全局的最高观光组合得分以及对应的景点下标组合。

通过上述优化思路,可以在低于暴力解法的时间复杂度下找到观光景点组合的最高得分。具体的代码实现会根据所选择的编程语言,按照这些思路来进行具体的变量定义、循环控制、数组操作等编写。