📌  相关文章
📜  通过给定数组两端存在的元素,使最长的非递减数组的长度最大化(1)

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

最长非递减序列长度问题介绍

问题描述

给定一个长度为 $n$ 的数组,数组中包含了一些不同的整数,假设确定了该数组的两个端点上的元素 $a$ 和 $b$($a <= b$)。那么我们可以选择从数组中选择一个子序列,使得该子序列是非递减的(即该子序列中的每个数都大于等于前面的数)。

现在的问题就是,如何通过选取恰当的子序列使得最后组成的子序列的长度最大。

解法

这是一个经典的DP问题。我们可以定义 $dp[i]$ 表示以第 $i$ 个元素作为结尾形成的最长递增子序列的长度,即 $i$ 一定要被选择作为子序列的一部分,并且要求该子序列以第 $i$ 个元素为结尾。

状态转移方程为 $dp[i] = \max_{j=0}^{i-1}{dp[j] + 1}(num_i >= num_j)$ ,意思是对于每个状态 $dp[i]$,我们枚举每一个前面的状态 $dp[j]$ 并尝试将其继承过来,如果这样做的话,得到的状态 $dp[i]$ 当然就等于 $dp[j] + 1$ 了。

最后统计一遍所有状态 $dp[i]$ 并取其最大值即可。

代码如下(使用 Python 实现):

def get_max_non_desc_array_len(nums: List[int], a: int, b: int) -> int:
    dp = [1] * len(nums)
    dp[a] = 1
    for i in range(a+1, b+1):
        for j in range(i):
            if nums[i] >= nums[j]:
                dp[i] = max(dp[i], dp[j]+1)
    return max(dp)

代码时间复杂度为 $O(n^2)$,空间复杂度为 $O(n)$。

总结

以上,我们介绍了如何通过选取恰当的子序列使得最后组成的子序列的长度最大,这是一个经典的DP问题,使用DP算法实现即可。