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

 `// 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[0][0] = 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 prefix 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 prefix 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 prefix 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 prefix 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<

## Javascript

 ``

Output:
`41`

.
Performance Analysis:

Time Complexity: O(20*n2k) in the worst case.

Space Complexity: O(n*k) in worst case.