Number of subsets with sum divisible by m

Given an array of integers, find number of subsequence such that the sum of the subsequence is divisible by m. It is given that sum of array elements is small.
Examples:

Input : arr[] = {1, 2, 3};
        m = 3;
Output : 3
Subsequence of given set are
{1}, {2}, {3}, {1, 2}, {2, 3}, {1, 3} and {1, 2, 3}. 
And their sums are 1, 2, 3, 3, 5, 4 and 6.

Input : arr[] = {1, 2, 3, 4};
        m = 2;
Output : 7
{2}, {4}, {1, 3}, {2, 4}, {1, 2, 3}, {1, 3, 4} 
and {1, 2, 3, 4}

A simple solution is to generate all possible subsets. For every subset, compute its sum and if sum is multiiple of m, increment result by 1. Time complexity of this approach is O(2len) where len is length of input array.

An efficient solution (for small values) is based on Dynamic Programming solution of subset sum problem. We make a 2D array of size sum x n.



C++

filter_none

edit
close

play_arrow

link
brightness_4
code

// C++ program which returns the Number of sub sequences 
// (or subsets) which are divisible by m.
#include <bits/stdc++.h>
using namespace std;
  
// Use Dynamic Programming to find
// sum of subsequences.
int sumSubSequence(vector<int> arr, int len, int m)
{
    // Find sum pf array elements
    int sum = 0;
    for (auto x : arr)
       sum += x;
  
    // dp[i][j] would be > 0 if arr[0..i-1] has
    // a subsequence with sum equal to j.
    vector<vector<int> > dp(len + 1, vector<int>(sum + 1, 0));
  
    // There is always sum equals zero
    for (int i = 0; i <= len; i++) 
        dp[i][0]++;
   
    // Fill up the dp table
    for (int i = 1; i <= len; i++) {
  
        dp[i][arr[i - 1]]++;
        for (int j = 1; j <= sum; j++) {
  
            if (dp[i - 1][j] > 0) {
                dp[i][j]++;
                dp[i][j + arr[i - 1]]++;
            }
        }
    }
  
    // Initialize the counter
    int count = 0;
    for (int j = 1; j <= sum; j++)
  
        // Check if the sum exists
        if (dp[len][j] > 0)
  
            // check sum is divisible by m
            if (j % m == 0)
                count += dp[len][j];
  
    return count;
}
  
// Driver Code
int main()
{
    vector<int> arr{ 1, 2, 3 };
    int m = 3;
    int len = arr.size();
    cout << sumSubSequence(arr, len, m) << endl;
    return 0;
}

chevron_right


Python3

filter_none

edit
close

play_arrow

link
brightness_4
code

# Python3 program which returns 
# the Number of sub sequences 
# (or subsets) which are divisible by m.
  
# Use Dynamic Programming to find
# sum of subsequences.
def sumSubSequence(arr, length, m):
  
    # Find sum pf array elements
    summ = 0
    for i in arr:
        summ += i
  
    # dp[i][j] would be > 0 if arr[0..i-1] has
    # a subsequence with sum equal to j.
    dp = [[0 for i in range(summ + 1)] 
             for j in range(length + 1)]
  
    # There is always sum equals zero
    for i in range(length + 1):
        dp[i][0] += 1
  
    # Fill up the dp table
    for i in range(1, length + 1):
        dp[i][arr[i - 1]] += 1
        for j in range(1, summ + 1):
            if dp[i - 1][j] > 0:
                dp[i][j] += 1
                dp[i][j + arr[i - 1]] += 1
  
    # Initialize the counter
    count = 0
    for i in range(1, summ + 1):
  
        # Check if the sum exists
        if dp[length][i] > 0:
  
            # check sum is divisible by m
            if i % m == 0:
                count += dp[length][i]
  
    return count
  
# Driver Code
if __name__ == "__main__":
    arr = [1, 2, 3]
    m = 3
    length = len(arr)
    print(sumSubSequence(arr, length, m))
  
# This code is contributed by
# sanjeev2552

chevron_right


Output:

3

Time complexity of the above approach is O(len*sum) where len is the size of the array and sum is the sum of all the integers in the array.



My Personal Notes arrow_drop_up

Although I started off with metallurgical & materials engineering, my true passion lies in computer science and computer engineering I hope to one day become a full stack developer and specialize in machine learning

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 : sanjeev2552