Skip to content
Related Articles

Related Articles

Improve Article
Sum over Subsets | Dynamic Programming
  • Difficulty Level : Hard

Prerequisite: Basic Dynamic Programming, Bitmasks 
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

 

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 <bits/stdc++.h>
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




<?php
// PHP program for brute force
// approach of SumOverSubsets DP
 
// function to print the sum
// over subsets value
function SumOverSubsets($a, $n)
{
 
    // array to store the SumOverSubsets
    $sos = array(1 << $n);
     
    for($i = 0 ;$i < (1 << $n); $i++)
        $sos[$i] = 0;
     
    // iterate for all possible x
    for ($x = 0; $x < (1 << $n); $x++)
    {
     
        // iterate for all possible
        // bitwise subsets
        for($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 ($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
?>

Javascript




<script>
    // Javascript program for brute force
    // approach of SumOverSubsets DP
     
    // function to print the
    // sum over subsets value
    function SumOverSubsets(a, n)
    {
      
        // array to store the SumOverSubsets
        let sos = new Array(1 << n);
        sos.fill(0);
          
          
        // iterate for all possible x
        for (let x = 0; x < (1 << n); x++)
        {
          
            // iterate for all possible
            // bitwise subsets
            for (let 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 (let i = 0; i < (1 << n); i++)
            document.write(sos[i] + " ");
    }
     
    let a = [7, 12, 14, 16];
    let n = 2;
    SumOverSubsets(a, n);
         
</script>

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{n \choose k}     . Therefore the total number of iterations is ∑{n \choose k}     2k = 3n 
Time Complexity: O(3n)
Below is the implementation of above idea: 
 



C++




// CPP program for sub-optimal
// approach of SumOverSubsets DP
#include <bits/stdc++.h>
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[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++)
    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

Python3




# Python program for sub-optimal
# approach of SumOverSubsets DP
 
# function to prthe sum over subsets value
def SumOverSubsets(a, n):
    sos = [0]*(1 << n)
 
    # iterate for all possible x
    for x in range((1 << n)):
        sos[x] = a[0]
         
        # iterate for the bitwise subsets only
        i = x
 
        while i > 0:
          sos[x] += a[i]
          i = ((i - 1) & x)
 
  # prall the subsets
    for i in range(1<<n):
        print(sos[i], end = " ")
 
# Driver Code
if __name__ == '__main__':
    a = [7, 12, 14, 16]
    n = 2
    SumOverSubsets(a, n)
 
# This code is contribued by mohit kumar 29.

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[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++)
        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




<?php
// PHP program for sub-optimal
// approach of SumOverSubsets DP
 
// function to print the
// sum over subsets value
function SumOverSubsets($a,$n)
{
 
    // array to store the SumOverSubsets
    $sos=array(1 << $n);
     
    // iterate for all possible x
    for ($x = 0; $x < (1 << $n); $x++)
    {
        $sos[$x] = $a[0];
     
        // iterate for the bitwise
        // subsets only
        for ($i = $x; $i > 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.
?>

Javascript




<script>   
    // Javascript program for sub-optimal
    // approach of SumOverSubsets DP
     
    // function to print the sum over
    // subsets value
    function SumOverSubsets(a, n)
    {
      
        // array to store the SumOverSubsets
        let sos = new Array((1 << n));
        sos.fill(0);
          
        // iterate for all possible x
        for (let x = 0; x < (1 << n); x++) {
            sos[x] = a[0];
          
            // iterate for the bitwise subsets only
            for (let i = x; i > 0; i = (i - 1) & x)
                sos[x] += a[i];
        }
          
        // print all the subsets
        for (let i = 0; i < (1 << n); i++)
            document.write(sos[i] + " ");
    }
     
    let a = [7, 12, 14, 16];
    let n = 2;
 
    SumOverSubsets(a, n);
 
</script>

Output: 
 

7 19 21 49 

Time Complexity: O(n*2n
Auxiliary Space: O(n2)
Reference
http://home.iitk.ac.in/~gsahil/cs498a/report.pdf
 

Attention reader! Don’t stop learning now. Get hold of all the important DSA concepts with the DSA Self Paced Course at a student-friendly price and become industry ready.  To complete your preparation from learning a language to DS Algo and many more,  please refer Complete Interview Preparation Course.

In case you wish to attend live classes with industry experts, please refer Geeks Classes Live




My Personal Notes arrow_drop_up
Recommended Articles
Page :