If the set S = {1,...,N} divided into two subsets with equal sums, this sum should be equal to half the sum S ; the sum of S is N(N+1)/2 , so the sum of each subset in the section must be N(N+1)/4 . It must also be an integer, so N(N+1)/2 must be even.
Thus, the question boils down to finding the number of subsets S whose sum is N(N+1)/4 . The total number of sections will be exactly half as many, since each section contains two such subsets, and none of the two sections has a subset.
That should be obvious.
Now we list the subsets of S that sum with k for any k and any set S Any such subset should have the greatest value, which should be an element of S The largest value must be either the largest element of S , or must be less than the largest element of S These two groups of subsets are different, so we can list them separately. Let me call the largest element S S max .
The second group is simple: these are simply subsets of S - { S max } that sum with k . We can find them by recursively calling a subset of lister. But the first group is almost as simple: each set in the group includes S max , and the rest of its elements are a set from S - { S max } , which adds up to k - S max , which again can be listed recursively. To complete the recursion, we note that if S is an empty set, then if k = 0 , then there is only one qualification subset (the empty set itself), and if k is not equal to 0, then there are no defining subsets. Each recursion removes one element from S , so ultimately the termination condition must be reached.
It should be clear that the subsets of S that will be used by the recursive function indicated above are just numbers from 1 to S max , so we can get rid of S altogether and write the recursion as follows:
Subsets(min, max, k) =
Subsets(min, max - 1, k)
⋃ { {max, P} | P ∈ Subsets(min, max - 1, k - max) }
But we only need to count the number of partitions, so we can simplify this a bit:
Count_Subsets(min, max, k) =
Count_Subsets(min, max - 1, k)
+ Count_Subsets(min, max - 1, k - max)
We need to complete the recursion by adding the final condition:
If min > max, Count_Subsets(min, max, k) = 1 if k = 0; otherwise 0
(Actually, just showing that recursion means that the value will be 1 when k decreases to 0 , and 0 if k less than 0 , so we can make the termination condition happen much earlier.)
This gives us a simple recursion for counting. But since he calls himself twice, it would be better to work backwards ("dynamic programming"). We need to calculate Count_Subsets(1, N, N*(N+1)/4) , which will require us to calculate the values of Count_Subsets(1, max, k) for all max values from 1 to N and from all k values from 0 to N * (N + 1) / 4. We do this starting from max = 0 and working until we reach min = N. And this is exactly what your algorithm does; i is max , and an array is a set of values for k from 0 to N(N+1)/4 .
By the way, as follows from the above description, a[j] should be increased by a[j - i] , and not by a[j - 1]