📌  相关文章
📜  最长递增子序列的长度,使得没有两个相邻元素互质(1)

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

求解最长递增子序列使得相邻元素不互质

在计算机科学中,最长递增子序列问题(Longest Increasing Subsequence,LIS)是一个经典的计算机科学问题。本文将介绍如何用动态规划解决最长递增子序列问题,并且要求相邻的元素不互质。

问题描述

一个序列 $S$,它的最长递增子序列的定义如下:

我们称一个序列 $L$ 为 $S$ 的一个子序列,当且仅当 $L$ 可以通过 $S$ 中删除一些元素(也可以不删除)得到。例如,序列 $[1,3,5,4,2]$ 的一个子序列是 $[1,5,2]$。我们称 $L$ 是 $S$ 的一个递增子序列,当且仅当在 $L$ 中的每个数都比前面的数大。

本题要求的是在一个给定的数列 $S$ 中,找到长度最长的递增子序列,但是要求相邻的元素不互质。也就是说,如果 $S_i$ 和 $S_{i+1}$ 是相邻的元素,它们之间的最大公约数 $gcd(S_i,S_{i+1})$ 不等于 1。

解法

我们可以用动态规划来解决这个问题。

对于序列 $S$,我们维护一个数组 $dp$,其中 $dp[i]$ 表示以 $S_i$ 为结尾的最长递增子序列并且 $S_i$ 和 $S_{i-1}$ 不互质。

对于每个 $dp[i]$,我们可以枚举 $j$($0\leq j<i$),如果 $gcd(S_j,S_i)=1$,则 $dp[i]$ 可以从 $dp[j]$ 转移而来。即:

$$ dp[i] = \max{dp[j]+1} (0\leq j<i, gcd(S_j,S_i)=1) $$

最后,我们找到 $dp$ 数组中的最大值,并返回它作为答案。

以下是 Python 代码实现:

def gcd(a, b):
    if b == 0:
        return a
    return gcd(b, a % b)

def longest_increasing_subsequence(S):
    n = len(S)
    dp = [1] * n
    for i in range(1, n):
        for j in range(i):
            if gcd(S[j], S[i]) == 1 and S[j] < S[i]:
                dp[i] = max(dp[i], dp[j] + 1)
    return max(dp)
总结

本文介绍了如何用动态规划解决最长递增子序列问题,并且要求相邻的元素不互质。我们维护了一个 $dp$ 数组,其中 $dp[i]$ 表示以 $S_i$ 为结尾的最长递增子序列并且 $S_i$ 和 $S_{i-1}$ 不互质。我们可以用动态规划的方式更新 $dp$ 数组,最终找到最大值作为答案。