最大化双分区的 GCD(最大公约数)之和?
Maximize the sum of GCDs (Greatest Common Divisors) of a bipartition?
给定一个正数数组。我想将数组分成 2 个不同的子集,以便它们的 gcd(最大公约数)的总和最大。
示例数组:{6,7,6,7}
。
答:两个必需的子集是:{6,6}
和{7,7}
;它们各自的gcd是6和7,它们的sum = 6+7=13
;这是可能的最大gcd总和。
Gcd:{8,12}
的 Gcd 是{4}
,因为 4 是除以 8 和 12 的最大数字。
注意:gcd(X)=X
子集仅包含一个元素的情况下。
我的方法:通过暴力强迫,我找到了数组的所有可能的子序列,然后,我找到了最大总和,但如果输入大小大于 30 个数字,这不起作用。我正在寻找一种更有效的方法。
额外:任何输入数字的最大大小为 10^9,时间限制:-1s 似乎不错,输入大小可能高达 10^5
我认为这实际上是一个简单的问题,冒充一个困难的问题。
首先,让我们忽略值多次出现的可能性。显然,最好将一个值的所有副本放在同一个集合中,因为将它们中的一些移动到其他地方只会损害 GCD(编辑:除非只有一个不同的值)。因此,我们假设所有元素都是不同的。此外,让 M 是任何元素的最大值。
这样想:有一个微不足道的解决方案,即在一侧取最高的元素,其余的元素在另一侧。"其余所有" - GCD 可能为 1(当然可能更高),因此此解决方案为您提供 M+1。
任何具有多个不同元素的输入子集的 GCD 都不能高于 M/2(因为这样的除数必须乘以另一个除数(至少为 2)才能得到不高于 M 的原始值)。所以编辑:最优解不能由两个集合组成,每个集合有多个不同的元素。它必须是一个元素与所有其他元素。
现在考虑两个最高的元素,值 M 和 M-d 表示一些 d。如果我们选择它们都不作为单例,它们都处于大群侧,这意味着该组最多有 gd(因为如果 g|M 和 g|M-d 然后 g|d);单例的贡献将不超过 M-d-1。因此,总分最多为 M-1 - 也就是说,小于我们在选择最高值时获得的分数。因此,输入中的最高或第二高(非重复)值必须位于其自己的集合中。
因此,您必须执行以下操作:
- 处理只有一个不同值的琐碎情况。
- 否则,获得 2 个最高元素;
- 计算所有 n-2 个最低元素的 GCD g_0。 计算 GCD 的g_with_highest = GCD(g_0, M
- ) 和 g_with_second_highest = GCD(g_0, M-d)。 通过将 M +
- g_with_second_highest 与 (M-d) + g_with_highest 进行比较来选择单例。
- 比较并显示使用最小值(a,b)和最大值(a、b)升序排列的4个数字
- 最小硬币更换问题(自上而下方法)
- 使用指针从C++中的数组中获取最大值
- 给定n个元素的m个集合.在C++中找到出现在最大集合数中的元素
- 芬威克树(BIT).找到具有给定累积频率的最小索引,单位为 O(logN)
- 如何加载(或映射)文件部分的最大大小,但适合在Windows上的RAM
- 如何修复我的最大公约数代码?它适用于除零和零以外的所有数字
- 求所有整数 1 到 N 的最大奇数除数之和
- 最大化双分区的 GCD(最大公约数)之和?
- 最大公因数函数
- 多项式最大公约数C++
- 实现欧几里得除法,根据两个正整数的线性组合编写这两个正整数的最大公约数
- 使用数组的 2 个数字的最大公约数
- 在编译时找到最大公约数
- C++最大公约数循环
- 直到n的所有数的最大公约数与n的和
- c++程序计算最大公约数
- 将数组划分为k个连续分区,使最大分区之和最小
- 使用欧几里得算法识别两个值的最大公约数 (GCD)
- 找出最大公约数的程序