Partition the array in K segments such that bitwise AND of individual segment sum is maximized
Last Updated :
21 Jun, 2022
Given an array of size N and an integer K. The task is to partition the array in K segments such that bitwise AND of individual segment sum is maximized. Find the maximum value of bitwise AND which can be obtained.
Examples:
Input : a[] = { 2, 5, 6, 9, 1, 3, 10, 12 }, K = 3
Output : 8
Explanation :
Maximum bitwise AND can be obtained by making cut at 3rd element and 5th element(1 based indexing)
(2+5+6)&(9+1)&(3+10+12) = 8
Input : a[] = { 1, 2, 7, 10, 23, 21, 6, 8, 7, 3 } , K = 2
Output : 41
Explanation:
Maximum bitwise AND can be obtained by making cut at 5th element(1 based indexing)
(1+2+7+10+23)&(21+6+8+7+3) = 41
Approach:
First, try to answer a simpler question: given an integer x and determine if it is possible to partition the given array into K segments such that the bitwise AND of sum of segments has all set bits of x?
Let’s denote the sum of elements in the ith segment by . Also, let’s call a segment good if has all set bits of x. It’s clear now that for a good segment i, AND(, x)=x.
Also, all K segments should be good for getting bitwise AND of x. Now to check whether we can partition the array into k good segments. We can use dynamic programming here.
Let dp[i][j]= true, denote that it is possible to partition first i elements into j segments such that all j are good segments otherwise false.
The recurrence for above dp is:
dp[i][j] is 1, if for some index k<i, AND(sum of a[k+1]…a[i], x)=x and dp[k][j-1]=1. Otherwise, dp[i][j] is 0
Build the dp table starting from the most significant bit of the possible answer greedily.
Below is the implementation of the above approach:
C++
#include <bits/stdc++.h>
using namespace std;
bool checkpossible( int mask, int * arr, int * prefix, int n,
int k)
{
bool dp[n + 1][k + 1];
memset (dp, 0, sizeof (dp));
dp[0][0] = 1;
for ( int i = 1; i <= n; i++) {
for ( int j = 1; j <= k; j++) {
for ( int l = i - 1; l >= 0; --l) {
if (dp[l][j - 1] && (((prefix[i] - prefix[l])
& mask) == mask)) {
dp[i][j] = 1;
break ;
}
}
}
}
return dp[n][k];
}
int Partition( int arr[], int n, int k)
{
int prefix[n+1];
for ( int i = 1; i <= n; i++) {
prefix[i] = prefix[i - 1] + arr[i];
}
int LOGS = 20;
int ans = 0;
for ( int i = LOGS; i >= 0; --i) {
if (checkpossible(ans | (1 << i), arr, prefix, n, k))
{
ans = ans | (1 << i);
}
}
return ans;
}
int main()
{
int arr[]={0, 1, 2, 7, 10, 23, 21, 6, 8, 7, 3}, k = 2;
int n = sizeof (arr)/ sizeof (arr[0])-1;
cout << Partition(arr, n, k);
return 0;
}
|
Java
class GFG
{
static boolean checkpossible( int mask, int arr[],
int prefix[], int n, int k)
{
int i,j;
boolean dp[][] = new boolean [n + 1 ][k + 1 ];
for (i = 0 ; i < n + 1 ; i++)
{
for (j = 0 ; j < k + 1 ; j++)
{
dp[i][j] = false ;
}
}
dp[ 0 ][ 0 ] = true ;
for ( i = 1 ; i <= n; i++)
{
for (j = 1 ; j <= k; j++)
{
for ( int l = i - 1 ; l >= 0 ; --l)
{
if (dp[l][j - 1 ] && (((prefix[i] - prefix[l])
& mask) == mask))
{
dp[i][j] = true ;
break ;
}
}
}
}
return dp[n][k];
}
static int Partition( int arr[], int n, int k)
{
int prefix[] = new int [n+ 1 ];
for ( int i = 1 ; i <= n; i++)
{
prefix[i] = prefix[i - 1 ] + arr[i];
}
int LOGS = 20 ;
int ans = 0 ;
for ( int i = LOGS; i >= 0 ; --i)
{
if (checkpossible(ans | ( 1 << i), arr, prefix, n, k))
{
ans = ans | ( 1 << i);
}
}
return ans;
}
public static void main (String[] args)
{
int arr[] = { 0 , 1 , 2 , 7 , 10 , 23 , 21 , 6 , 8 , 7 , 3 }, k = 2 ;
int n = arr.length - 1 ;
System.out.println(Partition(arr, n, k));
}
}
|
Python3
def checkpossible(mask,arr,prefix, n,k):
dp = [[ 0 for i in range (k + 1 )] for i in range (n + 1 )]
dp[ 0 ][ 0 ] = 1
for i in range ( 1 , n + 1 ):
for j in range ( 1 , k + 1 ):
for l in range (i - 1 , - 1 , - 1 ):
if (dp[l][j - 1 ] and (((prefix[i] - prefix[l]) & mask) = = mask)):
dp[i][j] = 1
break
return dp[n][k]
def Partition(arr, n, k):
prefix = [ 0 for i in range (n + 1 )]
for i in range ( 1 ,n + 1 ):
prefix[i] = prefix[i - 1 ] + arr[i]
LOGS = 20
ans = 0
for i in range (LOGS, - 1 , - 1 ):
if (checkpossible(ans | ( 1 << i), arr, prefix, n, k)):
ans = ans | ( 1 << i)
return ans
arr = [ 0 , 1 , 2 , 7 , 10 , 23 , 21 , 6 , 8 , 7 , 3 ]
k = 2
n = len (arr) - 1
print (Partition(arr, n, k))
|
C#
using System;
class GFG
{
static Boolean checkpossible( int mask, int []arr,
int []prefix,
int n, int k)
{
int i, j;
Boolean[,] dp = new Boolean[n + 1, k + 1];
for (i = 0; i < n + 1; i++)
{
for (j = 0; j < k + 1; j++)
{
dp[i, j] = false ;
}
}
dp[0, 0] = true ;
for ( i = 1; i <= n; i++)
{
for (j = 1; j <= k; j++)
{
for ( int l = i - 1; l >= 0; --l)
{
if (dp[l, j - 1] &&
(((prefix[i] - prefix[l]) &
mask) == mask))
{
dp[i, j] = true ;
break ;
}
}
}
}
return dp[n, k];
}
static int Partition( int []arr, int n, int k)
{
int []prefix = new int [n + 1];
for ( int i = 1; i <= n; i++)
{
prefix[i] = prefix[i - 1] + arr[i];
}
int LOGS = 20;
int ans = 0;
for ( int i = LOGS; i >= 0; --i)
{
if (checkpossible(ans | (1 << i),
arr, prefix, n, k))
{
ans = ans | (1 << i);
}
}
return ans;
}
public static void Main (String[] args)
{
int []arr = {0, 1, 2, 7, 10, 23,
21, 6, 8, 7, 3};
int k = 2;
int n = arr.Length - 1 ;
Console.WriteLine(Partition(arr, n, k));
}
}
|
Javascript
<script>
function checkpossible(mask, arr, prefix, n, k)
{
let i,j;
let dp = new Array(n + 1);
for (i = 0; i < n + 1; i++)
{
dp[i] = new Array(k + 1);
for (j = 0; j < k + 1; j++)
{
dp[i][j] = false ;
}
}
dp[0][0] = true ;
for (i = 1; i <= n; i++)
{
for (j = 1; j <= k; j++)
{
for (let l = i - 1; l >= 0; --l)
{
if (dp[l][j - 1] && (((prefix[i] - prefix[l])
& mask) == mask))
{
dp[i][j] = true ;
break ;
}
}
}
}
return dp[n][k];
}
function Partition(arr, n, k)
{
let prefix = new Array(n+1);
prefix.fill(0);
for (let i = 1; i <= n; i++)
{
prefix[i] = prefix[i - 1] + arr[i];
}
let LOGS = 20;
let ans = 0;
for (let i = LOGS; i >= 0; --i)
{
if (checkpossible(ans | (1 << i), arr, prefix, n, k))
{
ans = ans | (1 << i);
}
}
return ans;
}
let arr = [0, 1, 2, 7, 10, 23, 21, 6, 8, 7, 3], k = 2;
let n = arr.length - 1 ;
document.write(Partition(arr, n, k));
</script>
|
.
Performance Analysis:
Time Complexity: O(20*n2k) in the worst case.
Space Complexity: O(n*k) in worst case.
Share your thoughts in the comments
Please Login to comment...