Count subsets having product divisible by K
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 the 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++
#include <bits/stdc++.h>
using namespace std;
int cntSubDivK( int arr[], int N, int K, int rem,
vector<vector< int > >& dp)
{
if (N == 0) {
return rem == 0;
}
if (dp[N][rem] != -1) {
return dp[N][rem];
}
int X = cntSubDivK(arr, N - 1, K,
(rem * arr[N - 1]) % K, dp);
int Y = cntSubDivK(arr, N - 1, K, rem, dp);
dp[N][rem] = X + Y;
return X + Y;
}
int UtilCntSubDivK( int arr[], int N, int K)
{
vector<vector< int > > dp(N + 1, vector< int >(K + 1, -1));
return cntSubDivK(arr, N, K, 1, dp);
}
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);
}
|
Java
import java.util.*;
class GFG {
static int cntSubDivK( int arr[], int N, int K, int rem,
int [][] dp)
{
if (N == 0 ) {
return rem == 0 ? 1 : 0 ;
}
if (dp[N][rem] != - 1 ) {
return dp[N][rem];
}
int X = cntSubDivK(arr, N - 1 , K,
(rem * arr[N - 1 ]) % K, dp);
int Y = cntSubDivK(arr, N - 1 , K, rem, dp);
dp[N][rem] = X + Y;
return X + Y;
}
static int UtilCntSubDivK( int arr[], int N, int K)
{
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);
}
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));
}
}
|
Python3
def cntSubDivK(arr, N, K,
rem, dp):
if (N = = 0 ):
return rem = = 0
if (dp[N][rem] ! = - 1 ):
return dp[N][rem]
X = cntSubDivK(arr, N - 1 , K,
(rem * arr[N - 1 ]) % K, dp)
Y = cntSubDivK(arr, N - 1 ,
K, rem, dp)
dp[N][rem] = X + Y
return X + Y
def UtilCntSubDivK(arr, N, K):
dp = [[ - 1 for x in range (K + 1 )]
for y in range (N + 1 )]
return cntSubDivK(arr, N,
K, 1 , dp)
if __name__ = = "__main__" :
arr = [ 1 , 2 , 3 ,
4 , 5 , 6 ]
K = 60
N = len (arr)
print (UtilCntSubDivK(arr, N, K))
|
C#
using System;
class GFG {
static int cntSubDivK( int [] arr, int N, int K, int rem,
int [, ] dp)
{
if (N == 0) {
return rem == 0 ? 1 : 0;
}
if (dp[N, rem] != -1) {
return dp[N, rem];
}
int X = cntSubDivK(arr, N - 1, K,
(rem * arr[N - 1]) % K, dp);
int Y = cntSubDivK(arr, N - 1, K, rem, dp);
dp[N, rem] = X + Y;
return X + Y;
}
static int UtilCntSubDivK( int [] arr, int N, int K)
{
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);
}
static void Main()
{
int [] arr = { 1, 2, 3, 4, 5, 6 };
int K = 60;
int N = arr.Length;
Console.WriteLine(UtilCntSubDivK(arr, N, K));
}
}
|
Javascript
<script>
function cntSubDivK(arr, N, K, rem, dp)
{
if (N == 0)
{
return rem == 0 ? 1 : 0;
}
if (dp[N][rem] != -1)
{
return dp[N][rem];
}
let X = cntSubDivK(arr, N - 1, K,
(rem * arr[N - 1]) % K, dp);
let Y = cntSubDivK(arr, N - 1, K,
rem, dp);
dp[N][rem] = X + Y;
return X + Y;
}
function UtilCntSubDivK(arr, N, K)
{
let dp = new Array(N + 1);
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);
}
let arr = [ 1, 2, 3, 4, 5, 6 ];
let K = 60;
let N = arr.length;
document.write(UtilCntSubDivK(arr, N, K));
</script>
|
Time Complexity: O(N * K)
Space Complexity: O(N * K)
Last Updated :
15 Dec, 2022
Like Article
Save Article
Share your thoughts in the comments
Please Login to comment...