# Partition the array in K segments such that bitwise AND of individual segment sum is maximized

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

## Recommended: Please try your approach on {IDE} first, before moving on to the solution.

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++

 `// CPP program to find maximum possible AND ` `#include ` `using` `namespace` `std; ` ` `  `// Function to check whether a k segment partition  ` `// is possible such that bitwise AND is 'mask' ` `bool` `checkpossible(``int` `mask, ``int``* arr, ``int``* prefix, ``int` `n,  ` `                                                  ``int` `k) ` `{ ` `    ``// dp[i][j] stores whether it is possible to partition ` `    ``// first i elements into j segments such that all j  ` `    ``// segments are 'good' ` `    ``bool` `dp[n + 1][k + 1]; ` ` `  `    ``// Initialising dp ` `    ``memset``(dp, 0, ``sizeof``(dp)); ` `    ``dp = 1; ` ` `  `    ``// Filling dp in bottom-up manner ` `    ``for` `(``int` `i = 1; i <= n; i++) { ` `        ``for` `(``int` `j = 1; j <= k; j++) { ` `            ``// Finding a cut such that first l elements  ` `            ``// can be partitioned into j-1 'good' segments ` `            ``// and arr[l+1]+...+arr[i] is a 'good' segment ` `            ``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]; ` `} ` ` `  `// Function to find maximum possible AND ` `int` `Partition(``int` `arr[], ``int` `n, ``int` `k) ` `{ ` `    ``// Array to store prfix sums ` `    ``int` `prefix[n+1]; ` ` `  `    ``for` `(``int` `i = 1; i <= n; i++) { ` `        ``prefix[i] = prefix[i - 1] + arr[i]; ` `    ``} ` ` `  `    ``// Maximum no of bits in the possible answer ` `    ``int` `LOGS = 20; ` ` `  `    ``// This will store the final answer ` `    ``int` `ans = 0; ` ` `  `    ``// Constructing answer greedily selecting  ` `    ``// from the higher most bit ` `    ``for` `(``int` `i = LOGS; i >= 0; --i) { ` `        ``// Checking if array can be partitioned  ` `        ``// such that the bitwise AND is ans|(1<

## Java

 `// Java program to find maximum possible AND  ` ` `  `class` `GFG  ` `{ ` `     `  `    ``// Function to check whether a k segment partition  ` `    ``// is possible such that bitwise AND is 'mask'  ` `    ``static` `boolean` `checkpossible(``int` `mask, ``int` `arr[],  ` `                                ``int` `prefix[], ``int` `n, ``int` `k)  ` `    ``{  ` `        ``int` `i,j; ` `         `  `        ``// dp[i][j] stores whether it is possible to partition  ` `        ``// first i elements into j segments such that all j  ` `        ``// segments are 'good'  ` `        ``boolean` `dp[][] = ``new` `boolean``[n + ``1``][k + ``1``];  ` `     `  `        ``// Initialising dp  ` `        ``for``(i = ``0``; i < n + ``1``; i++) ` `        ``{ ` `            ``for``(j = ``0``; j < k + ``1``; j++) ` `            ``{ ` `                ``dp[i][j] = ``false` `; ` `            ``} ` `        ``} ` `         `  `        ``dp[``0``][``0``] = ``true``;  ` `     `  `        ``// Filling dp in bottom-up manner  ` `        ``for` `( i = ``1``; i <= n; i++)  ` `        ``{  ` `            ``for` `(j = ``1``; j <= k; j++) ` `            ``{  ` `                ``// Finding a cut such that first l elements  ` `                ``// can be partitioned into j-1 'good' segments  ` `                ``// and arr[l+1]+...+arr[i] is a 'good' segment  ` `                ``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];  ` `    ``}  ` `     `  `    ``// Function to find maximum possible AND  ` `    ``static` `int` `Partition(``int` `arr[], ``int` `n, ``int` `k)  ` `    ``{  ` `        ``// Array to store prfix sums  ` `        ``int` `prefix[] = ``new` `int``[n+``1``];  ` `     `  `        ``for` `(``int` `i = ``1``; i <= n; i++) ` `        ``{  ` `            ``prefix[i] = prefix[i - ``1``] + arr[i];  ` `        ``}  ` `     `  `        ``// Maximum no of bits in the possible answer  ` `        ``int` `LOGS = ``20``;  ` `     `  `        ``// This will store the final answer  ` `        ``int` `ans = ``0``;  ` `     `  `        ``// Constructing answer greedily selecting  ` `        ``// from the higher most bit  ` `        ``for` `(``int` `i = LOGS; i >= ``0``; --i)  ` `        ``{  ` `            ``// Checking if array can be partitioned  ` `            ``// such that the bitwise AND is ans|(1<

## Python3

 `# Python3 program to find maximum possible AND ` ` `  `# Function to check whether a k segment partition ` `# is possible such that bitwise AND is 'mask' ` `def` `checkpossible(mask,arr,prefix, n,k): ` `     `  `    ``# dp[i][j] stores whether it is possible to partition ` `    ``# first i elements into j segments such that all j ` `    ``# segments are 'good' ` `    ``dp``=``[[``0` `for` `i ``in` `range``(k``+``1``)] ``for` `i ``in` `range``(n ``+` `1``)] ` ` `  `    ``# Initialising dp ` `    ``dp[``0``][``0``] ``=` `1` ` `  `    ``# Filling dp in bottom-up manner ` `    ``for` `i ``in` `range``(``1``, n``+``1``): ` `        ``for` `j ``in` `range``(``1``, k``+``1``): ` `             `  `            ``# Finding a cut such that first l elements ` `            ``# can be partitioned into j-1 'good' segments ` `            ``# and arr[l+1]+...+arr[i] is a 'good' segment ` `            ``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] ` ` `  ` `  `# Function to find maximum possible AND ` `def` `Partition(arr, n, k): ` `    ``# Array to store prfix sums ` `    ``prefix``=``[``0` `for` `i ``in` `range``(n``+``1``)] ` ` `  `    ``for` `i ``in` `range``(``1``,n``+``1``): ` `        ``prefix[i] ``=` `prefix[i ``-` `1``] ``+` `arr[i] ` ` `  `    ``# Maximum no of bits in the possible answer ` `    ``LOGS ``=` `20` ` `  `    ``# This will store the final answer ` `    ``ans ``=` `0` ` `  `    ``# Constructing answer greedily selecting ` `    ``# from the higher most bit ` `    ``for` `i ``in` `range``(LOGS,``-``1``,``-``1``): ` `        ``# Checking if array can be partitioned ` `        ``# such that the bitwise AND is ans|(1<

## C#

 `// C# program to find maximum possible AND  ` `using` `System; ` `     `  `class` `GFG  ` `{ ` `     `  `    ``// Function to check whether a  ` `    ``// k-segment partition is possible ` `    ``// such that bitwise AND is 'mask'  ` `    ``static` `Boolean checkpossible(``int` `mask, ``int` `[]arr,  ` `                                 ``int` `[]prefix,  ` `                                 ``int` `n, ``int` `k)  ` `    ``{  ` `        ``int` `i, j; ` `         `  `        ``// dp[i,j] stores whether it is possible  ` `        ``// to partition first i elements into  ` `        ``// j-segments such that all j-segments are 'good'  ` `        ``Boolean[,] dp = ``new` `Boolean[n + 1, k + 1];  ` `     `  `        ``// Initialising dp  ` `        ``for``(i = 0; i < n + 1; i++) ` `        ``{ ` `            ``for``(j = 0; j < k + 1; j++) ` `            ``{ ` `                ``dp[i, j] = ``false``; ` `            ``} ` `        ``} ` `         `  `        ``dp[0, 0] = ``true``;  ` `     `  `        ``// Filling dp in bottom-up manner  ` `        ``for` `( i = 1; i <= n; i++)  ` `        ``{  ` `            ``for` `(j = 1; j <= k; j++) ` `            ``{  ` `                ``// Finding a cut such that first l elements  ` `                ``// can be partitioned into j-1 'good' segments  ` `                ``// and arr[l+1]+...+arr[i] is a 'good' segment  ` `                ``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];  ` `    ``}  ` `     `  `    ``// Function to find maximum possible AND  ` `    ``static` `int` `Partition(``int` `[]arr, ``int` `n, ``int` `k)  ` `    ``{  ` `        ``// Array to store prfix sums  ` `        ``int` `[]prefix = ``new` `int``[n + 1];  ` `     `  `        ``for` `(``int` `i = 1; i <= n; i++) ` `        ``{  ` `            ``prefix[i] = prefix[i - 1] + arr[i];  ` `        ``}  ` `     `  `        ``// Maximum no of bits in the possible answer  ` `        ``int` `LOGS = 20;  ` `     `  `        ``// This will store the final answer  ` `        ``int` `ans = 0;  ` `     `  `        ``// Constructing answer greedily selecting  ` `        ``// from the higher most bit  ` `        ``for` `(``int` `i = LOGS; i >= 0; --i)  ` `        ``{  ` `            ``// Checking if array can be partitioned  ` `            ``// such that the bitwise AND is ans|(1<

Output:

```41
```

Time Complexity : O( klog(S)), where S = + +….+ .

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 Check out this Author's contributed articles.

If you like GeeksforGeeks and would like to contribute, you can also write an article using contribute.geeksforgeeks.org or mail your article to contribute@geeksforgeeks.org. See your article appearing on the GeeksforGeeks main page and help other Geeks.

Please Improve this article if you find anything incorrect by clicking on the "Improve Article" button below.