📜  最长子序列,最大GCD(1)

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

最长子序列和最大GCD介绍

最长子序列和最大GCD是两个经典的算法问题。

最长子序列

最长子序列指的是一个序列中的一段连续子序列,并且该子序列的长度最长。

对于一个给定的序列,最长子序列有多种求解方案,其中比较经典的有动态规划和贪心算法。

动态规划的思路是,从头开始遍历整个序列,对于每个位置,把当前位置的数选或不选,分别求出相应的最长子序列长度,并记录下来。最终,最长的那个子序列长度即为所求。

贪心算法的思路是,从头开始遍历整个序列,维护两个变量:当前子序列长度和当前子序列的和。对于每个位置,如果当前子序列的和加上该位置的数仍小于等于该位置的数,那么就把该位置的数加入当前子序列,否则就另起一个子序列。最终,所有生成的子序列中长度最长的即为所求。

最大GCD

最大GCD指的是一个序列中任意两个数的最大公约数的最大值。

对于一个给定的序列,最大GCD也有多种求解方案,其中经典的有暴力和欧几里得算法。

暴力的思路是,枚举所有的数对,并求出它们的最大公约数,再选出其中最大的那个。时间复杂度为$O(n^2logn)$。

欧几里得算法的思路是,设$m$为所求数组的最大值,然后从$m$开始向下枚举,对于每个枚举到的数$x$,判断数组中是否至少存在两个数$y$和$z$,使得它们的最大公约数为$x$。如果存在,那么$x$即为所求。否则,继续往下枚举。时间复杂度为$O(nlogm)$。

综合应用

将最长子序列和最大GCD结合起来,即在一个序列中寻找一个最长的连续子序列,并且该子序列中任意两个数的最大公约数等于$k$。这个问题可以用动态规划和欧几里得算法结合起来求解。

具体来说,设$dp[i][j]$表示在序列的前$i$个元素中,以第$i$个元素结尾的符合要求的最长子序列长度,其中任意两个元素的最大公约数等于$j$。对于$dp[i][j]$,更新方式有两种情况:

  • 如果序列的第$i$个元素是符合要求的,那么$dp[i][j]$可以选择从$dp[i-1][j]$转移来,也可以选择从$dp[i-1][\gcd(j,a_i)]$转移来,取转移值的最大值即可。
  • 如果序列的第$i$个元素不符合要求,那么$dp[i][j]$的值应该为1,即只包含自己。

最终,所求即为$dp$数组中的最大值。时间复杂度为$O(nk\log m)$。

CODE

下面是用python实现最长子序列和最大GCD的代码。

def get_largest_subsequence(nums, k):
    n = len(nums)
    dp = [[0] * (k+1) for _ in range(n)]
    res = 1
    for i in range(n):
        dp[i][nums[i]] = 1
        for j in range(nums[i]+1, k+1):
            dp[i][j] = dp[i-1][j] if j % nums[i] else max(dp[i-1][j], dp[i-1][j//nums[i]] + 1)
        res = max(res, dp[i][k])
    return res

def get_max_gcd(nums):
    m = max(nums)
    for x in range(m, 0, -1):
        cnt = 0
        for y in nums:
            if y % x == 0:
                cnt += 1
            if cnt == 2:
                return x
    return 1

def get_largest_subsequence_with_max_gcd(nums, k):
    gcd = get_max_gcd(nums)
    if gcd > k:
        return 0
    nums = [num//gcd for num in nums]
    k //= gcd
    return get_largest_subsequence(nums, k) * gcd

以上是完整代码。

Markdown片段如下:

# 最长子序列和最大GCD介绍

最长子序列和最大GCD是两个经典的算法问题。

## 最长子序列

......

## 最大GCD

......

## 综合应用

将最长子序列和最大GCD结合起来,即......

## CODE

下面是用python实现最长子序列和最大GCD的代码。

```python

......

以上是完整代码。