Count subsets having product divisible by K - GeeksforGeeks

24 Apr, 2021
Given an array arr[] of size N and an integer K, the task is to count the number of subsets from the given array with product of elements divisible by K
Examples:
Input: arr[] = {1, 2, 3, 4, 5}, K = 60Output: 4Explanation: Subsets whose product of elements is divisible by K(= 60) are { {1, 2, 3, 4, 5}, {2, 3, 4, 5}, {3, 4, 5}, {1, 3, 4, 5} }
Input: arr[] = {1, 2, 3, 4, 5, 6}, K = 60Output: 16
Naive Approach: The simplest approach to solve this problem is to generate all possible subsets and for each subset, check if the product of its elements is divisible by K or not. If found to be true, then increment the count. Finally, print the count.
Time Complexity: O(N * 2N)Auxiliary Space: O(N)
Efficient Approach: To optimize the above approach the idea is to use Dynamic programming. Below is the recurrence relation and the base case:
Recurrence Relation: cntSubDivK(N, rem) = cntSubDivK(N – 1, (rem * arr[N – 1]) % K) + cntSubDivK(N – 1, rem). cntSubDivK(N, rem) store the count of subset having product divisible by K. rem: Store the remainder when K divides the product of all elements of the subset.  
Base Case: if N == 0 and rem == 0 then return 1. If N == 0 and rem != 0 then return 0.
Follow the steps below to solve the problem:
Initialize a 2D array, say dp[N][rem] to compute and store the values of all subproblems of the above recurrence relation.
Finally, return the value of dp[N][rem].
Below is the implementation of the above approach:
C++
Java
Python3
C#
Javascript
// C++ program to implement// the above approach #include <bits/stdc++.h>using namespace std; // Function to count the subsets whose// product of elements is divisible by Kint cntSubDivK(int arr[], int N, int K,               int rem, vector<vector<int> >& dp){    // If count of elements    // in the array is 0    if (N == 0) {         // If rem is 0, then return 1        // Otherwise, return 0        return rem == 0;    }     // If already computed    // subproblem occurred    if (dp[N][rem] != -1) {        return dp[N][rem];    }     // Stores count of subsets having product    // divisible by K when arr[N - 1]    // present in the subset    int X = cntSubDivK(arr, N - 1, K,                       (rem * arr[N - 1]) % K, dp);     // Stores count of subsets having product    // divisible by K when arr[N - 1] not    // present in the subset    int Y = cntSubDivK(arr, N - 1, K,                       rem, dp);     // Return total subset    return X + Y;} // Utility Function to count the subsets whose// product of elements is divisible by Kint UtilCntSubDivK(int arr[], int N, int K){     // Initialize a 2D array to store values    // of overlapping subproblems    vector<vector<int> > dp(N + 1,                            vector<int>(K + 1, -1));     return cntSubDivK(arr, N, K, 1, dp);} // Driver Codeint main(){    int arr[] = { 1, 2, 3, 4, 5, 6 };    int K = 60;    int N = sizeof(arr) / sizeof(arr[0]);    cout << UtilCntSubDivK(arr, N, K);}
// Java program to implement// the above approachimport java.util.*; class GFG{   // Function to count the subsets whose// product of elements is divisible by Kstatic int cntSubDivK(int arr[], int N, int K,                      int rem, int[][]dp){         // If count of elements    // in the array is 0    if (N == 0)    {                 // If rem is 0, then return 1        // Otherwise, return 0        return rem == 0 ? 1 : 0;    }     // If already computed    // subproblem occurred    if (dp[N][rem] != -1)    {        return dp[N][rem];    }     // Stores count of subsets having product    // divisible by K when arr[N - 1]    // present in the subset    int X = cntSubDivK(arr, N - 1, K,                       (rem * arr[N - 1]) % K, dp);     // Stores count of subsets having product    // divisible by K when arr[N - 1] not    // present in the subset    int Y = cntSubDivK(arr, N - 1, K,                       rem, dp);     // Return total subset    return X + Y;} // Utility Function to count the subsets whose// product of elements is divisible by Kstatic int UtilCntSubDivK(int arr[], int N, int K){         // Initialize a 2D array to store values    // of overlapping subproblems    int [][]dp = new int[N + 1][K + 1];         for(int i = 0; i < N + 1; i++)    {        for(int j = 0; j < K + 1; j++)            dp[i][j] = -1;    }    return cntSubDivK(arr, N, K, 1, dp);} // Driver Codepublic static void main(String args[]){    int arr[] = { 1, 2, 3, 4, 5, 6 };    int K = 60;    int N = arr.length;         System.out.println(UtilCntSubDivK(arr, N, K));}} // This code is contributed by SURENDRA_GANGWAR
# Python3 program to# implement the above# approach # Function to count the# subsets whose product# of elements is divisible# by Kdef cntSubDivK(arr, N, K,               rem, dp):     # If count of elements    # in the array is 0    if (N == 0):         # If rem is 0, then        # return 1 Otherwise,        # return 0        return rem == 0     # If already computed    # subproblem occurred    if (dp[N][rem] != -1):        return dp[N][rem]     # Stores count of subsets    # having product divisible    # by K when arr[N - 1]    # present in the subset    X = cntSubDivK(arr, N - 1, K,                   (rem * arr[N - 1]) % K, dp)     # Stores count of subsets having    # product divisible by K when    # arr[N - 1] not present in    # the subset    Y = cntSubDivK(arr, N - 1,                   K, rem, dp)     # Return total subset    return X + Y # Utility Function to count# the subsets whose product of# elements is divisible by Kdef UtilCntSubDivK(arr, N, K):     # Initialize a 2D array to    # store values of overlapping    # subproblems    dp = [[-1 for x in range(K + 1)]              for y in range(N + 1)]     return cntSubDivK(arr, N,                      K, 1, dp)   # Driver Codeif __name__ == "__main__":     arr = [1, 2, 3,           4, 5, 6]    K = 60    N = len(arr)    print(UtilCntSubDivK(arr, N, K)) # This code is contributed by Chitranayal
// C# program to implement// the above approachusing System; class GFG{     // Function to count the subsets whose// product of elements is divisible by Kstatic int cntSubDivK(int[] arr, int N, int K,                      int rem, int[,] dp){         // If count of elements    // in the array is 0    if (N == 0)    {                 // If rem is 0, then return 1        // Otherwise, return 0        return rem == 0 ? 1 : 0;    }      // If already computed    // subproblem occurred    if (dp[N, rem] != -1)    {        return dp[N, rem];    }         // Stores count of subsets having product    // divisible by K when arr[N - 1]    // present in the subset    int X = cntSubDivK(arr, N - 1, K,                      (rem * arr[N - 1]) % K, dp);                           // Stores count of subsets having product    // divisible by K when arr[N - 1] not    // present in the subset    int Y = cntSubDivK(arr, N - 1, K,                       rem, dp);                            // Return total subset    return X + Y;}  // Utility Function to count the subsets whose// product of elements is divisible by Kstatic int UtilCntSubDivK(int[] arr, int N, int K){         // Initialize a 2D array to store values    // of overlapping subproblems    int[,] dp = new int[N + 1, K + 1];          for(int i = 0; i < N + 1; i++)    {        for(int j = 0; j < K + 1; j++)            dp[i, j] = -1;    }    return cntSubDivK(arr, N, K, 1, dp);} // Driver codestatic void Main(){    int[] arr = { 1, 2, 3, 4, 5, 6 };    int K = 60;    int N = arr.Length;     Console.WriteLine(UtilCntSubDivK(arr, N, K));}} // This code is contributed by divyeshrabadiya07
<script> // JavaScript program to implement// the above approach // Function to count the subsets whose// product of elements is divisible by Kfunction cntSubDivK(arr, N, K, rem, dp){          // If count of elements    // in the array is 0    if (N == 0)    {                  // If rem is 0, then return 1        // Otherwise, return 0        return rem == 0 ? 1 : 0;    }      // If already computed    // subproblem occurred    if (dp[N][rem] != -1)    {        return dp[N][rem];    }      // Stores count of subsets having product    // divisible by K when arr[N - 1]    // present in the subset    let X = cntSubDivK(arr, N - 1, K,                 (rem * arr[N - 1]) % K, dp);      // Stores count of subsets having product    // divisible by K when arr[N - 1] not    // present in the subset    let Y = cntSubDivK(arr, N - 1, K,                       rem, dp);      // Return total subset    return X + Y;}  // Utility Function to count the subsets whose// product of elements is divisible by Kfunction UtilCntSubDivK(arr, N, K){          // Initialize a 2D array to store values    // of overlapping subproblems    let dp = new Array(N + 1);          // Loop to create 2D array using 1D array    for(var i = 0; i < dp.length; i++)    {        dp[i] = new Array(2);    }          for(let i = 0; i < N + 1; i++)    {        for(let j = 0; j < K + 1; j++)            dp[i][j] = -1;    }    return cntSubDivK(arr, N, K, 1, dp);} // Driver Codelet arr = [ 1, 2, 3, 4, 5, 6 ];let K = 60;let N = arr.length;  document.write(UtilCntSubDivK(arr, N, K)); // This code is contribute by target_2 </script>
16
 
Time Complexity: O(N * K)Space Complexity: O(N * K)
ukasp
SURENDRA_GANGWAR
divyeshrabadiya07
target_2
divisibility
subset
Arrays
Backtracking
Mathematical
Arrays
Mathematical
subset
Backtracking
Writing code in comment?
Please use ide.geeksforgeeks.org,
generate link and share the link here.
Maximum and minimum of an array using minimum number of comparisons
Top 50 Array Coding Problems for Interviews
Introduction to Arrays
Multidimensional Arrays in Java
Linear Search
N Queen Problem | Backtracking-3
Write a program to print all permutations of a given string
Given an array A[] and a number x, check for pair in A[] with sum as x (aka Two Sum)
Backtracking | Introduction
Rat in a Maze | Backtracking-2