Count Subsets with a Given Sum

Problem

Count the subsets of the array whose values add up to k. A subset is a choice of positions (the empty subset has the sum 0). Two subsets with the same values at different positions are different.

Constraints

  • 1 <= n <= 20
  • 0 <= a[i], k <= 1000

Examples

Input

5
1 2 3 4 5
5

Output

3

Solutions

Best approachTime O(2^n)Space O(n)

The include-exclude pattern: for every element decide to take it or to skip it. The recursion tree has 2^n leaves, so this is only for small n. Dynamic programming reduces it to O(n * k) when the values are non-negative.

Same code works in Java810172125Basic features only, so nothing changes between versions.
/*
 * Problem : Count subsets.
 * Input   : n, n integers, then k.
 * Output  : The count.
 * Approach: Take or skip.
 * Time    : O(2^n)
 * Space   : O(n)
 * Java    : 8 or newer.
 */
import java.util.Scanner;

public class Main {
        // Step 1: count(index, remaining) = the number of ways to choose from a[index..] so that the sum is "remaining".
        static long count(int[] a, int index, long remaining) {
            // Step 2: Base case. No more elements. There is exactly one way if nothing is left to add: the empty choice.
            if (index == a.length) {
                return remaining == 0 ? 1 : 0;
            }

            // Step 3: Two choices for this element: skip it, or take it.
            return count(a, index + 1, remaining) + count(a, index + 1, remaining - a[index]);
        }

    // This method solves the task. It receives the input and returns the answer.
    static long solve(int[] a, int k) {
        return count(a, 0, k);
    }

    public static void main(String[] args) {
        Scanner scanner = new Scanner(System.in);
        int size = scanner.nextInt();
        int[] a = new int[size];
        for (int i = 0; i < size; i++) {
            a[i] = scanner.nextInt();
        }
        int k = scanner.nextInt();
        System.out.println(solve(a, k));
    }
}
Hints (1)
  1. How many leaves does the recursion tree have?