找到其乘积为N的K数,使K数的最大值保持最小

时间:2018-06-09 08:11:13

标签: arrays algorithm sequence product

基本上,我们给出一个数字N和K,我们需要找到一个大小为K的数组,使得数组元素的乘积为N,最大化的元素被最小化。

例如:

420 3

ans:6 7 10 解释:420可以写为6,10和7的乘积。它也可以写成5 7 12但10(最多6 10和7)最小值为12(最大值为5 7 12)。

约束:数字&gt; 0; 0 <= N <0。 10 ^ 6; 1·; = K&LT; = 100

到目前为止我所做的是首先找到主要因素,但之后我想不出有效的方法来获得序列。

2 个答案:

答案 0 :(得分:2)

基本上,amritanshu有一个非常好idea:你有一个素数因子列表,并将这个列表拆分成一个包含K个最大因子的列表,另一个包含其他素因子:

[2, 2], [3, 5, 7]

然后将第一个列表中的最大元素与第二个列表中的最小元素相乘,并用结果覆盖第二个列表的元素。删除第一个列表中最大的元素。重复这些步骤,直到第一个列表为空:

[2, 2], [3, 5, 7]
[2], [6, 5, 7]  // 5 is now the smallest element
[], [6, 10, 7]

这是另一个例子:

N = 2310 = 2 * 3 * 5 * 7 * 11
K = 3

[2, 3], [5, 7, 11]
[2], [15, 7, 11]
[], [15, 14, 11]

但是,对于某些情况,例如N = 2310K = 2,此算法仍然不是完美的算法:

[2, 3, 5], [7, 11]
[2, 3], [35, 11]
[2], [35, 33]
[], [35, 66]  // better: [], [42, 55]

所以,我认为你实际上想要分解因子,使得因子尽可能接近N的Kth根。所以我想出了这个算法:

  • 计算R,即大于或等于N
  • 的第K个根的最小整数
  • 计算R和N的gcd
  • 如果gcd等于R,则将R添加到列表中,使用N / R, K-1递归调用算法,将结果添加到列表中并返回列表
  • 如果gcd不等于R,则将其添加到R并转到步骤2

这里有一些python代码:

import math

def gcd(a, b):

    while b:
        a, b = b, a % b
    return a

def root(N, K):

    R = int(math.exp(math.log(N) / K))
    if R ** K < N:
        R += 1
    return R

def find_factors(N, K):

    if K == 1:
        return [N]
    R = root(N, K)
    while True:
        GCD = gcd(N, R)
        if GCD == R:
            return [R] + find_factors(N // R, K-1)
        R += GCD

修改

我刚刚注意到,在许多情况下,此算法仍然会给出错误的结果。正确的方法是递增R,直到它除N

def find_factors(N, K):
    if K == 1:
        return [N]
    R = root(N, K)
    while True:
        if N % R == 0:
            return [R] + find_factors(N // R, K-1)
        R += 1

这样您就不需要gcd

答案 1 :(得分:0)

总的来说,我猜你需要对N进行分解,然后基本上采取一些暴力方法,试图将素因子组合成大致相等的组合因子。一般来说,这不应该太糟糕,因为在许多情况下,因素分解已经是最昂贵的部分。

原始回答(错误)(请参阅@gus的评论):

没有正确性证明,假设N>0K>0,伪代码:

  • N分解为素因子,存储到数组F
  • 找到m>=0
  • 的最小整数length(F) <= 2^m*K
  • F填写1以获取尺寸2^m*K
  • i=m down to 1
    • 排序F
    • 代表j=1 to 2^(i-1)*K
      • F[j] = F[j] * F[2^i*K+1-j](将最小值乘以最大值,依此类推)
    • F=F[1:2^(i-1)*K](删除F的上半部分)
  • F包含结果。

示例420 3

  • F={2,2,3,5,7}
  • m=1
  • F={1,2,2,3,5,7}
  • F={7,10,6} DONE

示例2310 2

  • F={2,3,5,7,11}
  • m=2
  • F={1,1,1,2,3,5,7,11}(填写2^m*K并排序)
  • F={11,7,5,6}(减少一半)
  • F={5,6,7,11}(排序)
  • F={55, 42} DONE

示例N=17^3*72K=3

  • F={2,2,2,3,3,17,17,17}
  • m=2
  • F={1,1,1,1,2,2,2,3,3,17,17,17}
  • F={17,17,17,3,6,4}
  • F={3,4,6,17,17,17}
  • F={3,4,6,17,17,17}
  • F={51,68,102}