Related Articles

Related Articles

Count subsets having product divisible by K
  • Last Updated : 08 Nov, 2020

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 = 60
Output: 4
Explanation: 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 = 60
Output: 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++

filter_none

edit
close

play_arrow

link
brightness_4
code

// 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 K
int 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 K
int 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 Code
int main()
{
    int arr[] = { 1, 2, 3, 4, 5, 6 };
    int K = 60;
    int N = sizeof(arr) / sizeof(arr[0]);
    cout << UtilCntSubDivK(arr, N, K);
}

chevron_right


Java

filter_none

edit
close

play_arrow

link
brightness_4
code

// Java program to implement
// the above approach
import java.util.*;
 
class GFG{
   
// Function to count the subsets whose
// product of elements is divisible by K
static 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 K
static 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 Code
public 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

chevron_right


Python3

filter_none

edit
close

play_arrow

link
brightness_4
code

# Python3 program to
# implement the above
# approach
 
# Function to count the
# subsets whose product
# of elements is divisible
# by K
def 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 K
def 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 Code
if __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

chevron_right


C#

filter_none

edit
close

play_arrow

link
brightness_4
code

// C# program to implement
// the above approach
using System;
 
class GFG{
     
// Function to count the subsets whose
// product of elements is divisible by K
static 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 K
static 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 code
static 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

chevron_right


Output: 

16









 

Time Complexity: O(N * K)
Space Complexity: O(N * K)

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.




My Personal Notes arrow_drop_up
Recommended Articles
Page :