The original dynamic programming algorithm applies, with a slight extension - in addition to remembering partial sums, you also need to remember number of ints used to get the sums.
In the original algorithm, assuming the target sum is M
and there are n
integers, you fill a boolean n
x M
array A
, where A[i,m]
is true iff sum m
can be achieved by picking (any number of) from first i+1
ints (assuming indexing from 0).
You can extend it to a three dimensional array n
xM
xk
, which has a similar property - A[i,m,l]
is true iff, sum m
can be achieved by picking exactly l
from first i+1
ints.
Assuming the ints are in array j[0..n-1]
:
The recursive relation is pretty similar - the field A[0,j[0],1]
is true (you pick j[0]
, getting sum j[0]
with 1 int (duh)), other fields in A[0,*,*]
are false and deriving fields in A[i+1,*,*]
from A[i,*,*]
is also similar to the original algorithm: A[i+1,m,l]
is true if A[i,m,l]
is true (if you can pick m
from first i
ints, then obviously you can pick m
from first i+1
ints) or if A[i, m - j[i+1], l-1]
is true (if you pick j[i+1]
then you increase the sum by j[i+1]
and the number of ints by 1).
If k
is small then obviously it makes sense to skip all of the above part and just iterate over all combinations of k
ints and checking their sums. k<=4
indeed seems like a sensible threshold.