基本上,我们给出一个数字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
到目前为止我所做的是首先找到主要因素,但之后我想不出有效的方法来获得序列。
答案 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 = 2310
,K = 2
,此算法仍然不是完美的算法:
[2, 3, 5], [7, 11]
[2, 3], [35, 11]
[2], [35, 33]
[], [35, 66] // better: [], [42, 55]
所以,我认为你实际上想要分解因子,使得因子尽可能接近N的Kth根。所以我想出了这个算法:
N / R, K-1
递归调用算法,将结果添加到列表中并返回列表这里有一些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>0
,K>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*72
,K=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}