Factoring a number into roughly equal factors
To answer your second question (which m
minimizes the sum of factors), it will always be optimal to split number into its prime factors. Indeed, for any positive composite number except 4
sum of its prime factors is less that the number itself, so any split that has composite numbers can be improved by splitting that composite numbers into its prime factors.
To answer your first question, greedy approaches suggested by others will not work, as I pointed out in the comments 4104
breaks them, greedy will immediately extract 8
as the first factor, and then will be forced to split the remaining number into [3, 9, 19]
, failing to find a better solution [6, 6, 6, 19]
. However, a simple DP can find the best solution. The state of the DP is the number we are trying to factor, and how many factors do we want to get, the value of the DP is the best sum possible. Something along the lines of the code below. It can be optimized by doing factorization smarter.
n = int(raw_input())
left = int(raw_input())
memo = {}
def dp(n, left): # returns tuple (cost, [factors])
if (n, left) in memo: return memo[(n, left)]
if left == 1:
return (n, [n])
i = 2
best = n
bestTuple = [n]
while i * i <= n:
if n % i == 0:
rem = dp(n / i, left - 1)
if rem[0] + i < best:
best = rem[0] + i
bestTuple = [i] + rem[1]
i += 1
memo[(n, left)] = (best, bestTuple)
return memo[(n, left)]
print dp(n, left)[1]
For example
[In] 4104
[In] 4
[Out] [6, 6, 6, 19]