Partition of a set into K subsets with equal sum using BitMask and DP
Last Updated :
11 Aug, 2021
Given an integer array arr[] of consisting of N integers, the task is check if it is possible to divide the given array into K non-empty subsets of equal sum such that every array element is part of a single subset.
Examples:
Input: arr[] = {2, 1, 4, 5, 6}, K = 3
Output: Yes
Explanation:
Possible subsets of given array are {2, 4}, (1, 5} and {6}
Input: arr[] = {2, 1, 5, 5, 6}, K = 3
Output: No
For the recursive approach, refer to Partition of a set into K subsets with equal sum.
Approach:
Follow the steps below to solve the problem:
- The idea is to use mask to determine the current state. The current state will tell us about the subset already formed ( which numbers are already selected ).
For example: arr[] = [2, 1, 4, 3, 5, 6, 2], mask = (1100101), which means that { 2, 1, 5, 2 } are already chosen in the current mask.
- For any current state mask, the jth element will be added to it based on the following two conditions:
- The jth bit is not set in the mask (mask&(1<<j) == 0)
- sum (mask) + arr[j] <= target ( where target = (Sum of array elements) / K)
- Maintain a table dp[] such that dp[i] store the sum of elements in mask i. So, the dp transitions will be:
dp[i | (1 << j)] = (dp[i] + arr[j]) % target
Illustration:
arr [ ] = [4, 3, 2, 3, 5, 2, 1], K = 4, tar = 5
dp[“1100101”] implies that { 4, 3, 5, 1 } are chosen
Hence, Sum = 4 + 3 + 5 + 1 = 13, 13 % 5 = 3.
Hence, dp[“1100101”] = 3
If dp[“11111…1111”] == 0 then that means we can find the solution.
Below is the implementation of above approach:
C++
#include <bits/stdc++.h>
using namespace std;
bool isKPartitionPossible( int arr[],
int N, int K)
{
if (K == 1)
return true ;
if (N < K)
return false ;
int sum = 0;
for ( int i = 0; i < N; i++)
sum += arr[i];
if (sum % K != 0)
return false ;
int target = sum / K;
int dp[(1 << 15)];
for ( int i = 0; i < (1 << N); i++)
dp[i] = -1;
dp[0] = 0;
for ( int mask = 0; mask < (1 << N); mask++) {
if (dp[mask] == -1)
continue ;
for ( int i = 0; i < N; i++) {
if (!(mask & (1 << i))
&& dp[mask]
+ arr[i]
<= target) {
dp[mask | (1 << i)]
= (dp[mask]
+ arr[i])
% target;
}
}
}
if (dp[(1 << N) - 1] == 0)
return true ;
else
return false ;
}
int main()
{
int arr[] = { 2, 1, 4, 5, 3, 3 };
int N = sizeof (arr) / sizeof (arr[0]);
int K = 3;
if (isKPartitionPossible(arr, N, K)) {
cout << "Partitions into equal " ;
cout << "sum is possible.\n" ;
}
else {
cout << "Partitions into equal " ;
cout << "sum is not possible.\n" ;
}
}
|
Java
import java.util.*;
class GFG{
static boolean isKPartitionPossible( int arr[],
int N, int K)
{
if (K == 1 )
return true ;
if (N < K)
return false ;
int sum = 0 ;
for ( int i = 0 ; i < N; i++)
sum += arr[i];
if (sum % K != 0 )
return false ;
int target = sum / K;
int []dp = new int [( 1 << 15 )];
for ( int i = 0 ; i < ( 1 << N); i++)
dp[i] = - 1 ;
dp[ 0 ] = 0 ;
for ( int mask = 0 ; mask < ( 1 << N); mask++)
{
if (dp[mask] == - 1 )
continue ;
for ( int i = 0 ; i < N; i++)
{
if (((mask & ( 1 << i)) == 0 ) &&
dp[mask] + arr[i] <= target)
{
dp[mask | ( 1 << i)] = (dp[mask] +
arr[i]) %
target;
}
}
}
if (dp[( 1 << N) - 1 ] == 0 )
return true ;
else
return false ;
}
public static void main(String[] args)
{
int arr[] = { 2 , 1 , 4 , 5 , 3 , 3 };
int N = arr.length;
int K = 3 ;
if (isKPartitionPossible(arr, N, K))
{
System.out.print( "Partitions into equal " );
System.out.print( "sum is possible.\n" );
}
else
{
System.out.print( "Partitions into equal " );
System.out.print( "sum is not possible.\n" );
}
}
}
|
Python3
def isKPartitionPossible(arr, N, K):
if (K = = 1 ):
return True
if (N < K):
return False
sum = 0
for i in range (N):
sum + = arr[i]
if ( sum % K ! = 0 ):
return False
target = sum / K
dp = [ 0 for i in range ( 1 << 15 )]
for i in range (( 1 << N)):
dp[i] = - 1
dp[ 0 ] = 0
for mask in range (( 1 << N)):
if (dp[mask] = = - 1 ):
continue
for i in range (N):
if ((mask & ( 1 << i) = = 0 ) and
dp[mask] + arr[i] < = target):
dp[mask | ( 1 << i)] = ((dp[mask] +
arr[i]) %
target)
if (dp[( 1 << N) - 1 ] = = 0 ):
return True
else :
return False
if __name__ = = '__main__' :
arr = [ 2 , 1 , 4 , 5 , 3 , 3 ]
N = len (arr)
K = 3
if (isKPartitionPossible(arr, N, K)):
print ( "Partitions into equal " \
"sum is possible." )
else :
print ( "Partitions into equal sum " \
"is not possible." )
|
C#
using System;
class GFG{
static bool isKPartitionPossible( int []arr,
int N, int K)
{
if (K == 1)
return true ;
if (N < K)
return false ;
int sum = 0;
for ( int i = 0; i < N; i++)
sum += arr[i];
if (sum % K != 0)
return false ;
int target = sum / K;
int []dp = new int [(1 << 15)];
for ( int i = 0; i < (1 << N); i++)
dp[i] = -1;
dp[0] = 0;
for ( int mask = 0; mask < (1 << N); mask++)
{
if (dp[mask] == -1)
continue ;
for ( int i = 0; i < N; i++)
{
if (((mask & (1 << i)) == 0) &&
dp[mask] + arr[i] <= target)
{
dp[mask | (1 << i)] = (dp[mask] +
arr[i]) %
target;
}
}
}
if (dp[(1 << N) - 1] == 0)
return true ;
else
return false ;
}
public static void Main(String[] args)
{
int []arr = { 2, 1, 4, 5, 3, 3 };
int N = arr.Length;
int K = 3;
if (isKPartitionPossible(arr, N, K))
{
Console.Write( "Partitions into equal " );
Console.Write( "sum is possible.\n" );
}
else
{
Console.Write( "Partitions into equal " );
Console.Write( "sum is not possible.\n" );
}
}
}
|
Javascript
<script>
function isKPartitionPossible(arr, N, K)
{
if (K == 1)
return true ;
if (N < K)
return false ;
let sum = 0;
for (let i = 0; i < N; i++)
sum += arr[i];
if (sum % K != 0)
return false ;
let target = sum / K;
let dp = Array.from({length: (1 << 15)}, (_, i) => 0);
for (let i = 0; i < (1 << N); i++)
dp[i] = -1;
dp[0] = 0;
for (let mask = 0; mask < (1 << N); mask++)
{
if (dp[mask] == -1)
continue ;
for (let i = 0; i < N; i++)
{
if (((mask & (1 << i)) == 0) &&
dp[mask] + arr[i] <= target)
{
dp[mask | (1 << i)] = (dp[mask] +
arr[i]) %
target;
}
}
}
if (dp[(1 << N) - 1] == 0)
return true ;
else
return false ;
}
let arr = [ 2, 1, 4, 5, 3, 3 ];
let N = arr.length;
let K = 3;
if (isKPartitionPossible(arr, N, K))
{
document.write( "Partitions into equal " );
document.write( "sum is possible.\n" );
}
else
{
document.write( "Partitions into equal " );
document.write( "sum is not possible.\n" );
}
</script>
|
Output:
Partitions into equal sum is possible.
Time Complexity: O (N * 2 N)
Auxiliary Space: O (2 N)
Share your thoughts in the comments
Please Login to comment...