# Sum over Subsets | Dynamic Programming

Consider the following problem where we will use Sum over subset Dynamic Programming to solve it.

Given an array of 2n integers, we need to calculate function F(x) = ∑Ai such that x&i==i for all x. i.e, i is a bitwise subset of x. i will be a bitwise subset of mask x, if x&i==i.

Examples:

```Input: A[] = {7, 12, 14, 16}  ,  n = 2
Output: 7, 19, 21, 49
Explanation: There will be 4 values of x: 0,1,2,3
So, we need to calculate F(0),F(1),F(2),F(3).
Now, F(0) = A0 = 7
F(1) =  A0 + A1 = 19
F(2) = A0 + A2 = 21
F(3) = A0 + A1 + A2 + A3 = 49

Input: A[] = {7, 11, 13, 16}  ,  n = 2
Output: 7, 18, 20, 47
Explanation: There will be 4 values of x: 0,1,2,3
So, we need to calculate F(0),F(1),F(2),F(3).
Now, F(0) = A0 = 7
F(1) =  A0 + A1 = 18
F(2) = A0 + A2 = 20
F(3) = A0 + A1 + A2 + A3 = 47
```

## Recommended: Please try your approach on {IDE} first, before moving on to the solution.

Brute-Force Approach:
Iterate for all the x from 0 to (2n-1) . Calculate the bitwise subsets of all the x and sum it up for every x.

Time-Complexity: O(4^n)

Below is the implementation of above idea:

## C++

 `// CPP program for brute force ` `// approach of SumOverSubsets DP ` `#include ` `using` `namespace` `std; ` ` `  `// function to print the sum over subsets value ` `void` `SumOverSubsets(``int` `a[], ``int` `n) { ` ` `  `  ``// array to store the SumOverSubsets ` `  ``int` `sos[1 << n] = {0}; ` ` `  `  ``// iterate for all possible x ` `  ``for` `(``int` `x = 0; x < (1 << n); x++) { ` ` `  `    ``// iterate for all possible bitwise subsets ` `    ``for` `(``int` `i = 0; i < (1 << n); i++) { ` ` `  `      ``// if i is a bitwise subset of x ` `      ``if` `((x & i) == i) ` `        ``sos[x] += a[i]; ` `    ``} ` `  ``} ` ` `  `  ``// printa all the subsets ` `  ``for` `(``int` `i = 0; i < (1 << n); i++) ` `    ``cout << sos[i] << ``" "``; ` `} ` ` `  `// Driver Code ` `int` `main() { ` `  ``int` `a[] = {7, 12, 14, 16}; ` `  ``int` `n = 2; ` `  ``SumOverSubsets(a, n); ` `  ``return` `0; ` `} `

## Java

 `// Java program for brute force ` `// approach of SumOverSubsets DP ` ` `  `class` `GFG{ ` ` `  `// function to print the ` `// sum over subsets value ` `static` `void` `SumOverSubsets(``int` `a[], ``int` `n) { ` ` `  `// array to store the SumOverSubsets ` `int` `sos[] = ``new` `int` `[``1` `<< n]; ` ` `  ` `  `// iterate for all possible x ` `for` `(``int` `x = ``0``; x < (``1` `<< n); x++) { ` ` `  `    ``// iterate for all possible ` `        ``// bitwise subsets ` `    ``for` `(``int` `i = ``0``; i < (``1` `<< n); i++) { ` ` `  `    ``// if i is a bitwise subset of x ` `    ``if` `((x & i) == i) ` `        ``sos[x] += a[i]; ` `    ``} ` `} ` ` `  `// printa all the subsets ` `for` `(``int` `i = ``0``; i < (``1` `<< n); i++) ` `    ``System.out.printf(``"%d "``, sos[i]); ` `} ` ` `  `// Driver Code ` `public` `static` `void` `main(String[] args) { ` `int` `a[] = {``7``, ``12``, ``14``, ``16``}; ` `int` `n = ``2``; ` `SumOverSubsets(a, n); ` `} ` `} ` ` `  `// This code is contributed by  ` `// Smitha Dinesh Semwal `

## Python3

 `# Python 3 program ` `# for brute force ` `# approach of SumOverSubsets DP ` ` `  `# function to print the ` `# sum over subsets value ` `def` `SumOverSubsets(a, n): ` ` `  `    ``# array to store ` `    ``# the SumOverSubsets ` `    ``sos ``=` `[``0``] ``*` `(``1` `<< n) ` `     `  `    ``# iterate for all possible x ` `    ``for` `x ``in` `range``(``0``,(``1` `<< n)):  ` `     `  `        ``# iterate for all ` `        ``# possible bitwise subsets ` `        ``for` `i ``in` `range``(``0``,(``1` `<< n)):   ` `     `  `            ``# if i is a bitwise subset of x ` `            ``if` `((x & i) ``=``=` `i): ` `                ``sos[x] ``+``=` `a[i] ` `             `  `     `  `     `  `    ``# printa all the subsets ` `    ``for` `i ``in` `range``(``0``,(``1` `<< n)):  ` `        ``print``(sos[i],end ``=` `" "``) ` ` `  ` `  `# Driver Code ` `a ``=` `[``7``, ``12``, ``14``, ``16``] ` `n ``=` `2` `SumOverSubsets(a, n) ` ` `  `# This code is contributed by ` `# Smitha Dinesh Semwal `

## C#

 `// C# program for brute force ` `// approach of SumOverSubsets DP ` `using` `System; ` ` `  `class` `GFG { ` `     `  `    ``// function to print the ` `    ``// sum over subsets value ` `    ``static` `void` `SumOverSubsets(``int` `[]a, ``int` `n) ` `    ``{ ` `     `  `        ``// array to store the SumOverSubsets ` `        ``int` `[]sos = ``new` `int` `[1 << n]; ` `         `  `         `  `        ``// iterate for all possible x ` `        ``for` `(``int` `x = 0; x < (1 << n); x++)  ` `        ``{ ` `         `  `            ``// iterate for all possible ` `            ``// bitwise subsets ` `            ``for` `(``int` `i = 0; i < (1 << n); i++)  ` `            ``{ ` `         `  `                ``// if i is a bitwise subset of x ` `                ``if` `((x & i) == i) ` `                    ``sos[x] += a[i]; ` `            ``} ` `        ``} ` `         `  `        ``// printa all the subsets ` `        ``for` `(``int` `i = 0; i < (1 << n); i++) ` `            ``Console.Write(sos[i] + ``" "``); ` `    ``} ` `     `  `    ``// Driver function ` `    ``public` `static` `void` `Main() ` `    ``{ ` `        ``int` `[]a = {7, 12, 14, 16}; ` `        ``int` `n = 2; ` `        ``SumOverSubsets(a, n); ` `    ``} ` `} ` ` `  `// This code is contributed by Sam007 `

## PHP

 ` `

Output:

`7 19 21 49 `

.

Sub-Optimal Approach:
The brute-force algorithm can be easily improved by just iterating over bitwise subsets. Instead of iterating for every i, we can simply iterate for the bitwise subsets only. Iterating backward for i=(i-1)&x gives us every bitwise subset, where i starts from x and ends at 1. If the mask x has k set bits, we do 2k iterations. A number of k set bits will have 2k bitwise subsets. Therefore total number of mask x with k set bits is . Therefore the total number of iterations is ∑ 2k = 3n

Time Complexity: O(3n)

Below is the implementation of above idea:

## C++

 `// CPP program for sub-optimal ` `// approach of SumOverSubsets DP ` `#include ` `using` `namespace` `std; ` ` `  `// function to print the sum over subsets value ` `void` `SumOverSubsets(``int` `a[], ``int` `n) { ` ` `  `  ``// array to store the SumOverSubsets ` `  ``int` `sos[1 << n] = {0}; ` ` `  `  ``// iterate for all possible x ` `  ``for` `(``int` `x = 0; x < (1 << n); x++) { ` `    ``sos[x] = a; ` ` `  `    ``// iterate for the bitwise subsets only ` `    ``for` `(``int` `i = x; i > 0; i = (i - 1) & x) ` `      ``sos[x] += a[i]; ` `  ``} ` ` `  `  ``// print all the subsets ` `  ``for` `(``int` `i = 0; i < (1 << n); i++) ` `    ``cout << sos[i] << ``" "``; ` `} ` ` `  `// Driver Code ` `int` `main() { ` `  ``int` `a[] = {7, 12, 14, 16}; ` `  ``int` `n = 2; ` `  ``SumOverSubsets(a, n); ` `  ``return` `0; ` `} `

## Java

 `// java program for sub-optimal ` `// approach of SumOverSubsets DP ` `public` `class` `GFG { ` `     `  `    ``// function to print the sum over ` `    ``// subsets value ` `    ``static` `void` `SumOverSubsets(``int` `a[], ``int` `n) ` `    ``{ ` `     `  `        ``// array to store the SumOverSubsets ` `        ``int` `sos[] = ``new` `int``[(``1` `<< n)]; ` `         `  `        ``// iterate for all possible x ` `        ``for` `(``int` `x = ``0``; x < (``1` `<< n); x++) { ` `            ``sos[x] = a[``0``]; ` `         `  `            ``// iterate for the bitwise subsets only ` `            ``for` `(``int` `i = x; i > ``0``; i = (i - ``1``) & x) ` `                ``sos[x] += a[i]; ` `        ``} ` `         `  `        ``// print all the subsets ` `        ``for` `(``int` `i = ``0``; i < (``1` `<< n); i++) ` `            ``System.out.print(sos[i] + ``" "``); ` `    ``} ` `     `  `    ``// Driver code ` `    ``public` `static` `void` `main(String args[]) ` `    ``{ ` `        ``int` `a[] = {``7``, ``12``, ``14``, ``16``}; ` `        ``int` `n = ``2``; ` `         `  `        ``SumOverSubsets(a, n); ` `    ``} ` `} ` ` `  `// This code is contributed by Sam007 `

## C#

 `// C# program for sub-optimal ` `// approach of SumOverSubsets DP ` `using` `System; ` ` `  `class` `GFG { ` `     `  `    ``// function to print the sum over ` `    ``// subsets value ` `    ``static` `void` `SumOverSubsets(``int` `[]a, ``int` `n) ` `    ``{ ` `     `  `        ``// array to store the SumOverSubsets ` `        ``int` `[]sos = ``new` `int``[(1 << n)]; ` `         `  `        ``// iterate for all possible x ` `        ``for` `(``int` `x = 0; x < (1 << n); x++) { ` `            ``sos[x] = a; ` `         `  `            ``// iterate for the bitwise subsets only ` `            ``for` `(``int` `i = x; i > 0; i = (i - 1) & x) ` `                ``sos[x] += a[i]; ` `        ``} ` `         `  `        ``// print all the subsets ` `        ``for` `(``int` `i = 0; i < (1 << n); i++) ` `        ``Console.Write(sos[i] + ``" "``); ` `    ``} ` `     `  `    ``// Driver code ` `    ``static` `void` `Main() ` `    ``{ ` `        ``int` `[]a = {7, 12, 14, 16}; ` `        ``int` `n = 2; ` `         `  `        ``SumOverSubsets(a, n); ` `    ``} ` `} ` ` `  `// This code is contributed by Sam007. `

## PHP

 ` 0; ``\$i` `= (``\$i` `- 1) & ``\$x``) ` `        ``\$sos``[``\$x``] += ``\$a``[``\$i``]; ` `    ``} ` `     `  `    ``// print all the subsets ` `    ``for` `(``\$i` `= 0; ``\$i` `< (1 << ``\$n``); ``\$i``++) ` `        ``echo` `\$sos``[``\$i``] . ``" "``; ` `} ` ` `  `// Driver Code ` `\$a` `= ``array``(7, 12, 14, 16); ` `\$n` `= 2; ` `SumOverSubsets(``\$a``, ``\$n``); ` ` `  `// This code is contributed by Sam007. ` `?> `

Output:

`7 19 21 49`

Dynamic Programming Approach:
In the brute-force approach, we iterated for every possible i for each mask x. We check if it was a bitwise subset and then summed it. In the sub-optimal approach, we iterated over the bitwise subsets only which reduced the complexity from O(4n) to O(3n). Having a closer look at the mask and the bitwise subset of every mask, we observe that we are performing repetitive calculations which can be reduced by memoization using Dynamic Programming. An index which has an off bit or an on bit is being visited by 2n masks more than once.

Let DP(mask, i) be the set of only those subsets of mask which differ in first i bits (zero-based from right).
For example Let mask be 10110101 in binary and i be 3, than those subsets which differ in first i bits (zero-based from right).
Example:

```(1011010, 1010010, 1011000, 1010000).
```

We will find repetitive masks whose first i bits will be same then the same bitwise subsets will be formed. We can memoize to obtain the previous results and reduce the number of steps by a significant amount.

Let’s consider the i-th bit to be 0, then no subset can differ from the mask in the i-th bit as it would mean that the numbers will have a 1 at i-th bit where the mask has a 0 which would mean that it is not a subset of the mask. Thus we conclude that the numbers now differ in the first (i-1) bits only. Hence,

```DP(mask, i)=DP(mask, i-1)
```

Now the second case, if the i-th bit is 1, it can be divided into two non-intersecting sets. One containing numbers with i-th bit as 1 and differing from mask in the next (i-1) bits. Second containing numbers with ith bit as 0 and differing from mask (2i) in next (i-1) bits. Hence,

```DP(mask, i) = DP(mask, i-1) U DP(mask 2i, i-1).
``` The above diagram explains how we can relate the DP(mask, i) sets on each other. The mask is represented in binary and is separated by a “.” with i. Elements of any set DP(mask, i) are the leaves in its subtree.The redblue prefixes depict that this part of the mask will be common to all its members/children while the red part of the mask is allowed to differ.

Looking at the rooted tree, we can figure out that for the same value of i, it can have a different value of mask.

Hence the two recurrence relations are:

```When i-th bit is off:

When i-th bit is on:
2. DP(mask, i) = DP(mask, i-1) U DP(mask 2i, i-1).```

Below is the implementation of above idea:

## C++

 `// CPP program for Dynamic Programming ` `// approach of SumOverSubsets DP ` ` `  `#include ` `using` `namespace` `std; ` ` `  `const` `int` `N = 1000; ` ` `  `// function to print the sum over subsets value ` `void` `SumOverSubsets(``int` `a[], ``int` `n) { ` `     `  `    ``// array to store the SumOverSubsets ` `    ``int` `sos[1 << n] = {0}; ` `     `  `    ``int` `dp[N][N]; ` `     `  `    ``// iterate for all possible x ` `    ``for` `(``int` `x = 0; x < (1 << n); x++)  ` `    ``{ ` `        ``// iterate till n ` `        ``for` `(``int` `i = 0; i < n; i++)  ` `        ``{ ` `            ``// if i-th bit is set ` `            ``if` `(x & (1 << i))  ` `            ``{ ` `                ``if` `(i == 0) ` `                    ``dp[x][i] = a[x] + a[x ^ (1 << i)];  ` `                ``else` `// dp recurrence ` `                     ``dp[x][i] = dp[x][i - 1] +  ` `                                ``dp[x ^ (1 << i)][i - 1];  ` `            ``}  ` `            ``else` `// i-th bit is not set ` `            ``{ ` `                ``if` `(i == 0) ` `                    ``dp[x][i] = a[x]; ``// base condition ` `                ``else` `                    ``dp[x][i] = dp[x][i - 1]; ``// dp recurrence ` `            ``} ` `        ``} ` `         `  `        ``// stores the final sum of subset of mask x ` `        ``sos[x] = dp[x][n - 1]; ` `    ``} ` `     `  `    ``// print all the sum of subsets ` `    ``for` `(``int` `i = 0; i < (1 << n); i++) ` `        ``cout << sos[i] << ``" "``; ` `} ` ` `  `// Driver Code ` `int` `main()  ` `{ ` `    ``int` `a[] = {7, 12, 14, 16}; ` `    ``int` `n = 2;     ` `    ``SumOverSubsets(a, n);     ` `    ``return` `0; ` `} `

## PHP

 ` ` ` `  ` `

Output:

`7 19 21 49 `

Time Complexity: O(n*2n)
Auxiliary Space: O(n2)

My Personal Notes arrow_drop_up Striver(underscore)79 at Codechef and codeforces D

If you like GeeksforGeeks and would like to contribute, you can also write an article using contribute.geeksforgeeks.org or mail your article to contribute@geeksforgeeks.org. See your article appearing on the GeeksforGeeks main page and help other Geeks.

Please Improve this article if you find anything incorrect by clicking on the "Improve Article" button below.

Improved By : Sam007, Shivi_Aggarwal

Article Tags :

Be the First to upvote.

Please write to us at contribute@geeksforgeeks.org to report any issue with the above content.