📜  门| GATE-CS-2016(Set 2)|问题8(1)

📅  最后修改于: 2023-12-03 14:58:31.147000             🧑  作者: Mango

介绍

本文将介绍 GATE-CS-2016(Set 2) 中的问题8。问题8是一道动态规划的题目,要求我们找出最长不连续递增子序列(LIS)。这道题需要熟悉递归和动态规划的思想,以及如何使用Memoization优化动态规划。

题目描述

给定一个长度为$n$的数列,找出其中最长的不连续递增子序列(LIS),并返回 LIS 的长度。

例子

给定序列:2, 5, 3, 7, 11, 8, 10, 13, 6

最长不连续递增子序列为:2, 5, 7, 11, 13

因此,该序列的最长不连续递增子序列长度为 5。

算法思路

我们可以使用动态规划的思想来解决这道题。设$LIS[i]$表示以第i个元素结尾的最长不连续递增子序列的长度。因此LIS[i]的值可以通过遍历前面i-1个元素并寻找其中比第i个元素小的元素来计算。具体来说,我们可以使用以下递归式:

$$LIS[i] = max(LIS[j]) + 1$$

其中 $j<i$ 且 $a[j]<a[i]$。

为了避免重复计算,我们可以使用Memoization技术,将已经计算好的LIS[i]的值存储在一个数组中,在下次需要使用时直接返回。这样可以大大减少计算量,并提高程序效率。

算法实现

下面是本题算法的Python实现代码:

def lis(seq):
    n = len(seq)
    memo = [None]*n

    def L(k):
        if memo[k] is not None:
            return memo[k]
        max_l = 1
        for i in range(k):
            if seq[i] < seq[k]:
                l_i = L(i)
                if l_i >= max_l:
                    max_l = l_i + 1
        memo[k] = max_l
        return max_l

    return max(L(i) for i in range(n))
算法分析
  • 时间复杂度:O(n^2)
  • 空间复杂度:O(n)
总结

本文介绍了如何使用动态规划的思想,解决最长不连续递增子序列(LIS)问题。我们讲述了如何使用Memoization技术优化动态规划,并提高程序效率。相信本文能够帮助读者更好地理解动态规划算法。