Maximum sum of Bitwise XOR of all elements of two equal length subsets
Given an array arr[] of N integers, where N is an even number. The task is to divide the given N integers into two equal subsets such that the sum of Bitwise XOR of all elements of two subsets is maximum.
Examples:
Input: N= 4, arr[] = {1, 2, 3, 4}
Output: 10
Explanation:
There are 3 ways possible:
(1, 2)(3, 4) = (1^2)+(3^4) = 10
(1, 3)(2, 4) = (1^3)+(2^3) = 8
(1, 4)(2, 3) = (1^4)+(2^3) = 6
Hence, the maximum sum = 10
Input: N= 6, arr[] = {4, 5, 3, 2, 5, 6}
Output: 17
Naive Approach: The idea is to check every possible distribution of N/2 pairs. Print the Bitwise XOR of the sum of all elements of two subsets which is maximum.
Time Complexity: O(N*N!)
Auxiliary Space: O(1)
Efficient Approach: To optimize the above approach, the idea is to use Dynamic Programming Using Bit Masking. Follow the below steps to solve the problem:
- Initially, the bitmask is 0, if the bit is set then the pair is already picked.
- Iterate through all the possible pairs and check if it is possible to pick a pair i.e., the bits of i and j are not set in the mask:
- If it is possible to take the pair then find the Bitwise XOR sum for the current pair and check for the next pair recursively.
- Else check for the next pair of elements.
- Keep updating the maximum XOR pair sum in the above step for each recursive call.
- Print the maximum value of all possible pairs stored in dp[mask].
Below is the implementation of the above approach:
C++
#include<bits/stdc++.h>
using namespace std;
int xorSum( int a[], int n,
int mask, int dp[])
{
if (dp[mask] != -1)
{
return dp[mask];
}
int max_value = 0;
for ( int i = 0; i < n; i++)
{
for ( int j = i + 1; j < n; j++)
{
if (i != j &&
(mask & (1 << i)) == 0 &&
(mask & (1 << j)) == 0)
{
max_value = max(max_value, (a[i] ^ a[j]) +
xorSum(a, n, (mask | (1 << i) |
(1 << j)), dp));
}
}
}
return dp[mask] = max_value;
}
int main()
{
int n = 4;
int arr[] = { 1, 2, 3, 4 };
int dp[(1 << n) + 5];
memset (dp, -1, sizeof (dp));
cout << (xorSum(arr, n, 0, dp));
}
|
Java
import java.util.*;
import java.io.*;
public class GFG {
public static int xorSum( int a[], int n,
int mask, int [] dp)
{
if (dp[mask] != - 1 ) {
return dp[mask];
}
int max_value = 0 ;
for ( int i = 0 ; i < n; i++) {
for ( int j = i + 1 ; j < n; j++) {
if (i != j
&& (mask & ( 1 << i)) == 0
&& (mask & ( 1 << j)) == 0 ) {
max_value = Math.max(
max_value,
(a[i] ^ a[j])
+ xorSum(a, n,
(mask | ( 1 << i)
| ( 1 << j)),
dp));
}
}
}
return dp[mask] = max_value;
}
public static void main(String args[])
{
int n = 4 ;
int arr[] = { 1 , 2 , 3 , 4 };
int dp[] = new int [( 1 << n) + 5 ];
Arrays.fill(dp, - 1 );
System.out.println(xorSum(arr, n, 0 , dp));
}
}
|
Python3
def xorSum(a, n, mask, dp):
if (dp[mask] ! = - 1 ):
return dp[mask]
max_value = 0
for i in range (n):
for j in range (i + 1 , n):
if (i ! = j and
(mask & ( 1 << i)) = = 0 and
(mask & ( 1 << j)) = = 0 ):
max_value = max (max_value,
(a[i] ^ a[j]) +
xorSum(a, n,
(mask | ( 1 << i) |
( 1 << j)), dp))
dp[mask] = max_value
return dp[mask]
n = 4
arr = [ 1 , 2 , 3 , 4 ]
dp = [ - 1 ] * (( 1 << n) + 5 )
print (xorSum(arr, n, 0 , dp))
|
C#
using System;
class GFG{
public static int xorSum( int []a, int n,
int mask, int [] dp)
{
if (dp[mask] != -1)
{
return dp[mask];
}
int max_value = 0;
for ( int i = 0; i < n; i++)
{
for ( int j = i + 1; j < n; j++)
{
if (i != j &&
(mask & (1 << i)) == 0 &&
(mask & (1 << j)) == 0)
{
max_value = Math.Max(
max_value,
(a[i] ^ a[j]) +
xorSum(a, n, (mask |
(1 << i) | (1 << j)), dp));
}
}
}
return dp[mask] = max_value;
}
public static void Main(String []args)
{
int n = 4;
int []arr = { 1, 2, 3, 4 };
int []dp = new int [(1 << n) + 5];
for ( int i = 0; i < dp.Length; i++)
dp[i] = -1;
Console.WriteLine(xorSum(arr, n, 0, dp));
}
}
|
Javascript
<script>
function xorSum(a, n, mask, dp)
{
if (dp[mask] != -1)
{
return dp[mask];
}
var max_value = 0;
for ( var i = 0; i < n; i++)
{
for ( var j = i + 1; j < n; j++)
{
if (i != j &&
(mask & (1 << i)) == 0 &&
(mask & (1 << j)) == 0)
{
max_value = Math.max(max_value, (a[i] ^ a[j]) +
xorSum(a, n, (mask | (1 << i) |
(1 << j)), dp));
}
}
}
return dp[mask] = max_value;
}
var n = 4;
var arr = [1, 2, 3, 4];
var dp = Array((1 << n) + 5).fill(-1);
document.write(xorSum(arr, n, 0, dp));
</script>
|
Time Complexity: O(N2*2N), where N is the size of the given array
Auxiliary Space: O(N)
Efficient approach : Using DP Tabulation method ( Iterative approach )
The approach to solve this problem is same but DP tabulation(bottom-up) method is better then Dp + memorization(top-down) because memorization method needs extra stack space of recursion calls.
Steps to solve this problem :
- Create a table to store the solution of the subproblems.
- Initialize the table with base cases
- Fill up the table iteratively
- Return the final solution
Implementation:
C++
#include<bits/stdc++.h>
using namespace std;
int xorSum( int a[], int n)
{
int dp[1 << n];
memset (dp, 0, sizeof (dp));
for ( int mask = 0; mask < (1 << n); mask++)
{
for ( int i = 0; i < n; i++)
{
for ( int j = i + 1; j < n; j++)
{
if ((mask & (1 << i)) == 0 &&
(mask & (1 << j)) == 0)
{
dp[mask | (1 << i) | (1 << j)] =
max(dp[mask | (1 << i) | (1 << j)],
dp[mask] + (a[i] ^ a[j]));
}
}
}
}
return dp[(1 << n) - 1];
}
int main()
{
int n = 4;
int arr[] = { 1, 2, 3, 4 };
cout << (xorSum(arr, n));
}
|
Java
import java.io.*;
import java.util.*;
public class Main {
static int xorSum( int a[], int n)
{
int dp[] = new int [ 1 << n];
Arrays.fill(dp, 0 );
for ( int mask = 0 ; mask < ( 1 << n); mask++) {
for ( int i = 0 ; i < n; i++) {
for ( int j = i + 1 ; j < n; j++)
{
if ((mask & ( 1 << i)) == 0 && (mask & ( 1 << j)) == 0 )
{
dp[mask | ( 1 << i) | ( 1 << j)] =
Math.max(dp[mask | ( 1 << i) | ( 1 << j)],
dp[mask] + (a[i] ^ a[j]));
}
}
}
}
return dp[( 1 << n) - 1 ];
}
public static void main(String[] args) {
int n = 4 ;
int arr[] = { 1 , 2 , 3 , 4 };
System.out.println(xorSum(arr, n));
}
}
|
Python
import math
def xorSum(a, n):
dp = [ 0 ] * ( 1 << n)
for mask in range ( 1 << n):
for i in range (n):
for j in range (i + 1 , n):
if (mask & ( 1 << i)) = = 0 and (mask & ( 1 << j)) = = 0 :
dp[mask | ( 1 << i) | ( 1 << j)] = max (
dp[mask | ( 1 << i) | ( 1 << j)], dp[mask] + (a[i] ^ a[j]))
return dp[( 1 << n) - 1 ]
if __name__ = = '__main__' :
n = 4
arr = [ 1 , 2 , 3 , 4 ]
print (xorSum(arr, n))
|
C#
using System;
public class Program {
static int xorSum( int [] a, int n)
{
int [] dp = new int [1 << n];
Array.Fill(dp, 0);
for ( int mask = 0; mask < (1 << n); mask++)
{
for ( int i = 0; i < n; i++)
{
for ( int j = i + 1; j < n; j++)
{
if ((mask & (1 << i)) == 0 &&
(mask & (1 << j)) == 0)
{
dp[mask | (1 << i) | (1 << j)] =
Math.Max(dp[mask | (1 << i) | (1 << j)],
dp[mask] + (a[i] ^ a[j]));
}
}
}
}
return dp[(1 << n) - 1];
}
static void Main( string [] args)
{
int n = 4;
int [] arr = { 1, 2, 3, 4 };
Console.WriteLine(xorSum(arr, n));
}
}
|
Javascript
function xorSum(a, n) {
let dp = new Array(1 << n).fill(0);
for (let mask = 0; mask < (1 << n); mask++) {
for (let i = 0; i < n; i++) {
for (let j = i + 1; j < n; j++) {
if ((mask & (1 << i)) == 0 && (mask & (1 << j)) == 0) {
dp[mask | (1 << i) | (1 << j)] =
Math.max(
dp[mask | (1 << i) | (1 << j)],
dp[mask] + (a[i] ^ a[j])
);
}
}
}
}
return dp[(1 << n) - 1];
}
let n = 4;
let arr = [1, 2, 3, 4];
console.log(xorSum(arr, n));
|
Time Complexity: O(N2*2N)
Auxiliary Space: O(N)
Last Updated :
04 Apr, 2023
Like Article
Save Article
Share your thoughts in the comments
Please Login to comment...