Maximum sum of Bitwise XOR of all elements of two equal length subsets
Last Updated :
04 Apr, 2023
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++
// C++ program for the above approach
#include<bits/stdc++.h>
using namespace std;
// Function that finds the maximum
// Bitwise XOR sum of the two subset
int xorSum(int a[], int n,
int mask, int dp[])
{
// Check if the current state is
// already computed
if (dp[mask] != -1)
{
return dp[mask];
}
// Initialize answer to minimum value
int max_value = 0;
// Iterate through all possible pairs
for (int i = 0; i < n; i++)
{
for (int j = i + 1; j < n; j++)
{
// Check whether ith bit and
// jth bit of mask is not
// set then pick the pair
if (i != j &&
(mask & (1 << i)) == 0 &&
(mask & (1 << j)) == 0)
{
// For all possible pairs
// find maximum value pick
// current a[i], a[j] and
// set i, j th bits in mask
max_value = max(max_value, (a[i] ^ a[j]) +
xorSum(a, n, (mask | (1 << i) |
(1 << j)), dp));
}
}
}
// Store the maximum value
// and return the answer
return dp[mask] = max_value;
}
// Driver Code
int main()
{
int n = 4;
// Given array arr[]
int arr[] = { 1, 2, 3, 4 };
// Declare Initialize the dp states
int dp[(1 << n) + 5];
memset(dp, -1, sizeof(dp));
// Function Call
cout << (xorSum(arr, n, 0, dp));
}
// This code is contributed by Rohit_ranjan
Java
// Java program for the above approach
import java.util.*;
import java.io.*;
public class GFG {
// Function that finds the maximum
// Bitwise XOR sum of the two subset
public static int xorSum(int a[], int n,
int mask, int[] dp)
{
// Check if the current state is
// already computed
if (dp[mask] != -1) {
return dp[mask];
}
// Initialize answer to minimum value
int max_value = 0;
// Iterate through all possible pairs
for (int i = 0; i < n; i++) {
for (int j = i + 1; j < n; j++) {
// Check whether ith bit and
// jth bit of mask is not
// set then pick the pair
if (i != j
&& (mask & (1 << i)) == 0
&& (mask & (1 << j)) == 0) {
// For all possible pairs
// find maximum value pick
// current a[i], a[j] and
// set i, j th bits in mask
max_value = Math.max(
max_value,
(a[i] ^ a[j])
+ xorSum(a, n,
(mask | (1 << i)
| (1 << j)),
dp));
}
}
}
// Store the maximum value
// and return the answer
return dp[mask] = max_value;
}
// Driver Code
public static void main(String args[])
{
int n = 4;
// Given array arr[]
int arr[] = { 1, 2, 3, 4 };
// Declare Initialize the dp states
int dp[] = new int[(1 << n) + 5];
Arrays.fill(dp, -1);
// Function Call
System.out.println(xorSum(arr, n, 0, dp));
}
}
Python3
# Python3 program to implement
# the above approach
# Function that finds the maximum
# Bitwise XOR sum of the two subset
def xorSum(a, n, mask, dp):
# Check if the current state is
# already computed
if(dp[mask] != -1):
return dp[mask]
# Initialize answer to minimum value
max_value = 0
# Iterate through all possible pairs
for i in range(n):
for j in range(i + 1, n):
# Check whether ith bit and
# jth bit of mask is not
# set then pick the pair
if(i != j and
(mask & (1 << i)) == 0 and
(mask & (1 << j)) == 0):
# For all possible pairs
# find maximum value pick
# current a[i], a[j] and
# set i, j th bits in mask
max_value = max(max_value,
(a[i] ^ a[j]) +
xorSum(a, n,
(mask | (1 << i) |
(1 << j)), dp))
# Store the maximum value
# and return the answer
dp[mask] = max_value
return dp[mask]
# Driver Code
n = 4
# Given array arr[]
arr = [ 1, 2, 3, 4 ]
# Declare Initialize the dp states
dp = [-1] * ((1 << n) + 5)
# Function call
print(xorSum(arr, n, 0, dp))
# This code is contributed by Shivam Singh
C#
// C# program for the above approach
using System;
class GFG{
// Function that finds the maximum
// Bitwise XOR sum of the two subset
public static int xorSum(int []a, int n,
int mask, int[] dp)
{
// Check if the current state is
// already computed
if (dp[mask] != -1)
{
return dp[mask];
}
// Initialize answer to minimum value
int max_value = 0;
// Iterate through all possible pairs
for(int i = 0; i < n; i++)
{
for(int j = i + 1; j < n; j++)
{
// Check whether ith bit and
// jth bit of mask is not
// set then pick the pair
if (i != j &&
(mask & (1 << i)) == 0 &&
(mask & (1 << j)) == 0)
{
// For all possible pairs
// find maximum value pick
// current a[i], a[j] and
// set i, j th bits in mask
max_value = Math.Max(
max_value,
(a[i] ^ a[j]) +
xorSum(a, n, (mask |
(1 << i) | (1 << j)), dp));
}
}
}
// Store the maximum value
// and return the answer
return dp[mask] = max_value;
}
// Driver Code
public static void Main(String []args)
{
int n = 4;
// Given array []arr
int []arr = { 1, 2, 3, 4 };
// Declare Initialize the dp states
int []dp = new int[(1 << n) + 5];
for(int i = 0; i < dp.Length; i++)
dp[i] = -1;
// Function call
Console.WriteLine(xorSum(arr, n, 0, dp));
}
}
// This code is contributed by amal kumar choubey
JavaScript
<script>
// JavaScript program for the above approach
// Function that finds the maximum
// Bitwise XOR sum of the two subset
function xorSum(a, n, mask, dp)
{
// Check if the current state is
// already computed
if (dp[mask] != -1)
{
return dp[mask];
}
// Initialize answer to minimum value
var max_value = 0;
// Iterate through all possible pairs
for (var i = 0; i < n; i++)
{
for (var j = i + 1; j < n; j++)
{
// Check whether ith bit and
// jth bit of mask is not
// set then pick the pair
if (i != j &&
(mask & (1 << i)) == 0 &&
(mask & (1 << j)) == 0)
{
// For all possible pairs
// find maximum value pick
// current a[i], a[j] and
// set i, j th bits in mask
max_value = Math.max(max_value, (a[i] ^ a[j]) +
xorSum(a, n, (mask | (1 << i) |
(1 << j)), dp));
}
}
}
// Store the maximum value
// and return the answer
return dp[mask] = max_value;
}
// Driver Code
var n = 4;
// Given array arr[]
var arr = [1, 2, 3, 4];
// Declare Initialize the dp states
var dp = Array((1 << n) + 5).fill(-1);
// Function Call
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++
// C++ program for above approach
#include<bits/stdc++.h>
using namespace std;
// Function that finds the maximum
// Bitwise XOR sum of the two subset
int xorSum(int a[], int n)
{
// Declare dp table and initialize
// with all elements as 0
int dp[1 << n];
memset(dp, 0, sizeof(dp));
// Fill the dp table
for (int mask = 0; mask < (1 << n); mask++)
{
for (int i = 0; i < n; i++)
{
for (int j = i + 1; j < n; j++)
{
// Check whether ith bit and
// jth bit of mask is not set
// then pick the pair
if ((mask & (1 << i)) == 0 &&
(mask & (1 << j)) == 0)
{
// Update dp table with
// maximum value pick
// current a[i], a[j] and
// set i, j th bits in mask
dp[mask | (1 << i) | (1 << j)] =
max(dp[mask | (1 << i) | (1 << j)],
dp[mask] + (a[i] ^ a[j]));
}
}
}
}
// Return the maximum value
return dp[(1 << n) - 1];
}
// Driver Code
int main()
{
int n = 4;
// Given array arr[]
int arr[] = { 1, 2, 3, 4 };
// Function Call
cout << (xorSum(arr, n));
}
// this code is contributed by bhardwajji
Java
// java code addition
import java.io.*;
import java.util.*;
public class Main {
// Function that finds the maximum
// Bitwise XOR sum of the two subset
static int xorSum(int a[], int n)
{
// Declare dp table and initialize
// with all elements as 0
int dp[] = new int[1 << n];
Arrays.fill(dp, 0);
// Fill the dp table
for (int mask = 0; mask < (1 << n); mask++) {
for (int i = 0; i < n; i++) {
for (int j = i + 1; j < n; j++)
{
// Check whether ith bit and
// jth bit of mask is not set
// then pick the pair
if ((mask & (1 << i)) == 0 && (mask & (1 << j)) == 0)
{
// Update dp table with
// maximum value pick
// current a[i], a[j] and
// set i, j th bits in mask
dp[mask | (1 << i) | (1 << j)] =
Math.max(dp[mask | (1 << i) | (1 << j)],
dp[mask] + (a[i] ^ a[j]));
}
}
}
}
// Return the maximum value
return dp[(1 << n) - 1];
}
// Driver Code
public static void main(String[] args) {
int n = 4;
// Given array arr[]
int arr[] = { 1, 2, 3, 4 };
// Function Call
System.out.println(xorSum(arr, n));
}
}
// The code is contributed by Nidhi goel.
Python
# Python program for above approach
import math
# Function that finds the maximum
# Bitwise XOR sum of the two subset
def xorSum(a, n):
# Declare dp table and initialize
# with all elements as 0
dp = [0]*(1 << n)
# Fill the dp table
for mask in range(1 << n):
for i in range(n):
for j in range(i+1, n):
# Check whether ith bit and
# jth bit of mask is not set
# then pick the pair
if (mask & (1 << i)) == 0 and (mask & (1 << j)) == 0:
# Update dp table with
# maximum value pick
# current a[i], a[j] and
# set i, j th bits in mask
dp[mask | (1 << i) | (1 << j)] = max(
dp[mask | (1 << i) | (1 << j)], dp[mask] + (a[i] ^ a[j]))
# Return the maximum value
return dp[(1 << n) - 1]
# Driver Code
if __name__ == '__main__':
n = 4
# Given array arr[]
arr = [1, 2, 3, 4]
# Function Call
print(xorSum(arr, n))
# This code is contributed by user_dtewbxkn77n
C#
using System;
public class Program {
// Function that finds the maximum
// Bitwise XOR sum of the two subset
static int xorSum(int[] a, int n)
{
// Declare dp table and initialize
// with all elements as 0
int[] dp = new int[1 << n];
Array.Fill(dp, 0);
// Fill the dp table
for (int mask = 0; mask < (1 << n); mask++)
{
for (int i = 0; i < n; i++)
{
for (int j = i + 1; j < n; j++)
{
// Check whether ith bit and
// jth bit of mask is not set
// then pick the pair
if ((mask & (1 << i)) == 0 &&
(mask & (1 << j)) == 0)
{
// Update dp table with
// maximum value pick
// current a[i], a[j] and
// set i, j th bits in mask
dp[mask | (1 << i) | (1 << j)] =
Math.Max(dp[mask | (1 << i) | (1 << j)],
dp[mask] + (a[i] ^ a[j]));
}
}
}
}
// Return the maximum value
return dp[(1 << n) - 1];
}
// Driver Code
static void Main(string[] args)
{
int n = 4;
// Given array arr[]
int[] arr = { 1, 2, 3, 4 };
// Function Call
Console.WriteLine(xorSum(arr, n));
}
}
JavaScript
// JavaScript code equivalent of the Java code above
function xorSum(a, n) {
// Declare dp table and initialize
// with all elements as 0
let dp = new Array(1 << n).fill(0);
// Fill the dp table
for (let mask = 0; mask < (1 << n); mask++) {
for (let i = 0; i < n; i++) {
for (let j = i + 1; j < n; j++) {
// Check whether ith bit and jth bit of mask is not set
// then pick the pair
if ((mask & (1 << i)) == 0 && (mask & (1 << j)) == 0) {
// Update dp table with
// maximum value pick
// current a[i], a[j] and
// set i, j th bits in mask
dp[mask | (1 << i) | (1 << j)] =
Math.max(
dp[mask | (1 << i) | (1 << j)],
dp[mask] + (a[i] ^ a[j])
);
}
}
}
}
// Return the maximum value
return dp[(1 << n) - 1];
}
// Driver Code
let n = 4;
// Given array arr[]
let arr = [1, 2, 3, 4];
// Function Call
console.log(xorSum(arr, n));
Time Complexity: O(N2*2N)
Auxiliary Space: O(N)
Similar Reads
Maximum subset with bitwise OR equal to k Given an array of non-negative integers and an integer k, find the subset of maximum length with bitwise OR equal to k. Examples: Input : arr[] = [1, 4, 2] k = 3 Output : [1, 2] Explanation: The bitwise OR of 1 and 2 equals 3. It is not possible to obtain a subset of length greater than 2. Input : a
8 min read
Queries to calculate maximum Bitwise XOR of X with any array element not exceeding M Given an array arr[] consisting of N non-negative integers and a 2D array queries[][] consisting of queries of the type {X, M}, the task for each query is to find the maximum Bitwise XOR of X with any array element whose value is at most M. If it is not possible to find the Bitwise XOR, then print "
15+ min read
Maximize total set bits of elements in N sized Array with sum M Given two integers N and M denoting the size of an array and the sum of the elements of the array, the task is to find the maximum possible count of total set bits of all the elements of the array such that the sum of the elements is M. Examples: Input: N = 1, M = 15Output: 4Explanation: Since N =1,
8 min read
Smallest element with K set bits such that sum of Bitwise AND of each array element with K is maximum Given an array arr[] consisting of N integers and integer K, the task is to find the smallest integer X with exactly K set bits such that the sum of Bitwise AND of X with every array element arr[i] is maximum. Examples: Input: arr[] = {3, 4, 5, 1}, K = 1Output: 4Explanation: Consider the value of X
8 min read
Minimum elements to be removed to make pairwise Bitwise XOR 0 or 1 Given an array X[] of length N. Then your task is to output the minimum number of elements needed to remove so that the Bitwise XOR of any pair is either 0 or 1. Examples: Input: N = 5, X[] = {1, 2, 3, 5, 2}Output: 2Explanation: If we remove 1 and 5 from X[] then the remaining elements are {2, 3, 2}
6 min read