I have a number n and I have to split it into k numbers such that all k numbers are distinct, the sum of the k numbers is equal to n and k is maximum. Example if n is 9 then the answer should be 1,2,6. If n is 15 then answer should be 1,2,3,4,5.
This is what I've tried -
void findNum(int l, int k, vector<int>& s)
{
if (k <= 2 * l) {
s.push_back(k);
return;
}
else if (l == 1) {
s.push_back(l);
findNum(l + 1, k - 1, s);
}
else if(l == 2) {
s.push_back(l);
findNum(l + 2, k - 2, s);
}
else{
s.push_back(l);
findNum(l + 1, k - l, s);
}
}
Initially k = n and l = 1. Resulting numbers are stored in s. This solution even though returns the number n as a sum of k distinct numbers but it is the not the optimal solution(k is not maximal). Example output for n = 15 is 1,2,4,8. What changes should be made to get the correct result?
Approach: An efficient solution is to call a recursive function starting with zero (because zero is always possible). If function call is fun(x) then recursively call fun(x + a) and fun(x + b) (because if x is possible then x + a and x + b are also possible). Return out of the function if x > n.
Greedy algorithm works for this problem. Just start summing up from 1 to m
such that sum(1...m) <= n
. As soon as it exceeds, add the excess to m-1
. Numbers from 1 upto m|m-1 will be the answer.
eg.
18
1+2+3+4+5 < 18
+6 = 21 > 18
So, answer: 1+2+3+4+(5+6-(21-18))
28
1+2+3+4+5+6+7 = 28
So, answer: 1+2+3+4+5+6+7
Pseudocode (in constant time, complexity O(1))
Find k such that, m * (m+1) > 2 * n
Number of terms = m-1
Terms: 1,2,3...m-2,(m-1 + m - (sum(1...m) - n))
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With