📜  门| GATE CS Mock 2018年|套装2 |问题21(1)

📅  最后修改于: 2023-12-03 15:12:38.393000             🧑  作者: Mango

门 | GATE CS Mock 2018年 | 套装 2 | 问题 21

本题涉及动态规划,要求编写一个 Python 函数来解决以下问题。

问题描述

给定一个由正整数组成的数组 arr,以及一个正整数 k,请编写一个函数来返回数组中最长的连续子序列的长度,使得该子序列的元素之间的差的绝对值不超过 k

函数定义
def longest_subsequence(arr: List[int], k: int) -> int:
    pass
输入格式
  • arr:一个由正整数组成的列表,其中 $1\leqslant n\leqslant10^4$,$1\leqslant arr_i\leqslant10^6$。这里 $n$ 表示列表 arr 的长度,$arr_i$ 表示 arr 中第 $i$ 个元素的值。
  • k:一个正整数,其中 $1\leqslant k\leqslant10^6$。
输出格式
  • 一个整数,表示最长的连续子序列的长度。
例子
样例 1
assert longest_subsequence([1, 5, 3, 9, 10, 11, 12, 13, 15], 3) == 7

解释:

样例中最长的连续子序列是 [9, 10, 11, 12, 13, 15],长度为 7。

样例 2
assert longest_subsequence([1, 2, 3, 4, 5, 6, 7, 8, 9, 10], 1) == 10

解释:

样例中最长的连续子序列是整个列表 arr,长度为 10。

解题思路

这是一道动态规划问题。我们可以用类似贪心的思路来解决。

设 $dp_i$ 为以 $i$ 结尾的最长的连续子序列的长度,则:

$$ dp_i = \begin{cases} 1, & i=1 \ dp_j + 1, & arr_i - arr_j \leqslant k, j<i \ 1, & otherwise \end{cases} $$

其中 $i=1$ 时,$dp_1=1$。当 $arr_i - arr_j \leqslant k$ 时,$j$ 是在 $1\sim i-1$ 中寻找,找到 $i$ 之前最靠近 $i$ 的元素,对应的 $dp_j$ 即为以 $j$ 结尾的最长的连续子序列的长度,所以 $dp_i=dp_j+1$。

最终的答案是 $dp$ 数组中的最大值。

代码实现

下面给出 Python 实现: