Let A be the collection of input numbers.
Initialize a boolean array B to store in B[i] whether or not we can 'make' i by adding the numbers in A as described in the problem. Make all B[i] initially FALSE.
Then, pseudocode:
for i = 1 to N
if B[i] && (not A.Contains(i))
continue next i
if not A.Contains(i)
countAdded++
for j = N-i downTo 1
if B[j] then B[j+i] = TRUE
B[i] = TRUE
next i
Explanation:
Within the (main) loop (i): B contains TRUE for the values that we can construct with the values in A that are lower than i. Initially, therefore, with i=1 all B are FALSE.
Then, for each i we have two aspects to consider: (a) is B[i] already TRUE? If not we'll have to add i; (b) is i present in A? because, see previous remark, at this point we haven't yet processed that A-value. So, even if B[i] is already TRUE we'll have to flag TRUE for all (other) B that we may reach with i.
Consequently:
For each i we first determine if either of these two cases applies, and if not, we skip to the next i.
Then, if A does NOT (yet) contain i, it must be the case that B[i] is FALSE, see skip-condition, and therefore we'll add i (to A, conceptually, but it's not necessary to actually put it into A).
Next, either we had i in A initially, or we have just added it. In any case, we'll need to flag B TRUE for all values that can be constructed with this new i. To do so, we better scan existing B in downward fashion; otherwise we may add i to a "new" B-value that has i already as constituent.
Finally, B[i] itself is set TRUE (it may already be TRUE...), simply because i is in A (orginally, or by adding)