📌  相关文章
📜  长度为K的子序列X,使得gcd(X [0],X [1])+(X [2],X [3])+…最大化(1)

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

最大化子序列的最大公约数

给定长度为n的数组a和正整数k,要求选出长度为k的子序列X使得X的最大公约数尽可能大,求最大的最大公约数和。

解决思路

首先,我们需要了解最大公约数的性质。最大公约数是一组数的公共因子中最大的一个。

假设a数组中最大的数为max,那么最大的最大公约数一定不会超过max。如果我们枚举最大公约数mid,那么我们可以将a中所有能被mid整除的数选中,取k个中gcd最大的那个。

因此,我们可以使用二分查找,从大到小枚举mid,每次检查是否存在长度为k的子序列的gcd大于等于mid。

算法实现
def gcd(a, b):
    while b:
        a, b = b, a % b
    return a

def check(a, k, mid):
    cnt = 0
    for i in range(len(a)):
        if a[i] % mid == 0:
            cnt += 1
            if cnt == k:
                return True
    return False

def max_gcd_sum(a, k):
    l, r = 1, max(a)
    ans = 0
    while l <= r:
        mid = (l + r) // 2
        if check(a, k, mid):
            ans = max(ans, mid)
            l = mid + 1
        else:
            r = mid - 1
    return ans * k
复杂度分析
  • 时间复杂度:O(nlog(max(a))),其中n为数组a的长度,max(a)为a数组中的最大值。需要枚举max(a)次,每次检查长度为k的子序列的gcd大于等于mid需要O(n)的时间复杂度。因此总时间复杂度为O(nlog(max(a)))。
  • 空间复杂度:O(1)。