I will describe a bit simpler solution:
Let A be initial array, let Pos and Neg be sets of all positive (nonnegative, to be exact) and all negative numbers from A respectively.
Let us look at the problem from another point of view. Instead of choosing subsets from A
and minimizing sums of both positive and negative numbers, we will consider an equivalent problem:
Take MaxSum := sum of all numbers in Pos. Clearly, this is the biggest possible sum we can get.
Starting from MaxSum, we can get any subset sum of A by adding some numbers from Neg and subtracting some numbers from Pos. Note, that both operations subtract some nonnegative value from MaxSum! Thus, we’ve reduced our problem to a simpler one:
Simpler Problem:
Take Abs := set of absolute values of Pos and Neg (<=> set of all absolute values of A).
We need to choose k smallest sums from Abs to subtract from MaxSum.
Solution:
Take smallest m, such that 2^m >= min(2^N, k). By the constrains of the problem we have m <= 11.
Obviously, k smallest sums from Abs are some subsets of the smallest m numbers of Abs.
Thus, we can consider all such 2^m <= 2048 subsets and get smallest sums
(s_1, s_2, ... s_k). The final answer will be (MaxSum - s_1, MaxSum - s_2, ... MaxSum - s_k).
Time complexity:
O(N) to find MaxSum
O(N log(N)), for example, to find m smallest numbers from Abs. In fact, finding m smallest numbers can be done with O(N + m log(m)) complexity, see this. Since m <= 11, we can say that time complexity is also O(N).
O(1) to consider 2^m <= 2048 sums from m numbers (using bit masks, for example).
Total time complexity: O(Nlog(N)) for straightforward approach and O(N) for optimized approach.
Space complexity: O(N + k) (<=> O(N), since k <= 2000).