# Maximum subset sum such that no two elements in set have same digit in them

Last Updated : 18 Apr, 2023

Given an array of N elements. Find the subset of elements which has maximum sum such that no two elements in the subset has common digit present in them.
Examples:

Input : array[] = {22, 132, 4, 45, 12, 223}
Output : 268
Maximum Sum Subset will be = {45, 223} .
All possible digits are present except 1.
But to include 1 either 2 or both 2 and 3 have
to be removed which result in smaller sum value.
Input : array[] = {1, 21, 32, 4, 5 }
Output : 42

• Here we can use Dynamic Programming and Bit Masking to solve this question.
• Consider a 10-bit representation of every number where each bit is 1 if digit corresponding to that bit is present in that number.
• Now maintain a dp[i], which stores the maximum possible sum which can be achieved with all those digits present in the set, corresponding to the bit positions which are 1 in Binary Representation of i.
• Recurrence Relation will be of the form dp[i] = max(dp[i], dp[i^mask] + a[j]) , for all those j from 1 to n such that mask (10-bit Representation of a[j]) satisfy i || mask = i. (Since then only we can assure that all digit available in i are satisfied).

Below is the implementation of the above approach:

## C++

 // C++ implementation of above approach #include using namespace std; int dp[1024];    // Function to create mask for every number int get_binary(int u) {     int ans = 0;     while (u) {         int rem = u % 10;         ans |= (1 << rem);         u /= 10;     }        return ans; }    // Recursion for Filling DP array int recur(int u, int array[], int n) {     // Base Condition     if (u == 0)         return 0;     if (dp[u] != -1)         return dp[u];        int temp = 0;     for (int i = 0; i < n; i++) {         int mask = get_binary(array[i]);            // Recurrence Relation         if ((mask | u) == u) {             dp[u] = max(max(0,                     dp[u ^ mask]) + array[i], dp[u]);         }     }        return dp[u]; }    // Function to find Maximum Subset Sum int solve(int array[], int n) {     // Initialize DP array     for (int i = 0; i < (1 << 10); i++) {         dp[i] = -1;     }        int ans = 0;        // Iterate over all possible masks of 10 bit number     for (int i = 0; i < (1 << 10); i++) {         ans = max(ans, recur(i, array, n));     }        return ans; }    // Driver Code int main() {     int array[] = { 22, 132, 4, 45, 12, 223 };     int n = sizeof(array) / sizeof(array[0]);           cout << solve(array, n); }

## Java

 // Java implementation of above approach import java.io.*;   class GFG {       static int []dp = new int [1024];   // Function to create mask for every number static int get_binary(int u) {     int ans = 0;     while (u > 0)           {         int rem = u % 10;         ans |= (1 << rem);         u /= 10;     }       return ans; }   // Recursion for Filling DP array static int recur(int u, int []array, int n) {     // Base Condition     if (u == 0)         return 0;     if (dp[u] != -1)         return dp[u];       for (int i = 0; i < n; i++)     {         int mask = get_binary(array[i]);           // Recurrence Relation         if ((mask | u) == u)         {             dp[u] = Math.max(Math.max(0,                     dp[u ^ mask]) + array[i], dp[u]);         }     }       return dp[u]; }   // Function to find Maximum Subset Sum static int solve(int []array, int n) {     // Initialize DP array     for (int i = 0; i < (1 << 10); i++)     {         dp[i] = -1;     }       int ans = 0;       // Iterate over all possible masks of 10 bit number     for (int i = 0; i < (1 << 10); i++)     {         ans = Math.max(ans, recur(i, array, n));     }       return ans; }   // Driver Code static public void main (String[] args) {     int []array = { 22, 132, 4, 45, 12, 223 };     int n = array.length;           System.out.println(solve(array, n)); } }   // This code is contributed by anuj_67..

## Python3

 # Python3 implementation of above approach   dp = [0]*1024;   # Function to create mask for every number def get_binary(u) :       ans = 0;     while (u) :         rem = u % 10;         ans |= (1 << rem);         u //= 10;     return ans;     # Recursion for Filling DP array def recur(u, array, n) :       # Base Condition     if (u == 0) :         return 0;               if (dp[u] != -1) :         return dp[u];       temp = 0;     for i in range(n) :         mask = get_binary(array[i]);           # Recurrence Relation         if ((mask | u) == u) :             dp[u] = max(max(0, dp[u ^ mask]) + array[i], dp[u]);       return dp[u];     # Function to find Maximum Subset Sum def solve(array, n)  :     i = 0           # Initialize DP array     while(i < (1 << 10)) :         dp[i] = -1;         i += 1           ans = 0;       i = 0     # Iterate over all possible masks of 10 bit number     while(i < (1 << 10)) :         ans = max(ans, recur(i, array, n));                   i += 1           return ans;   # Driver Code if __name__ ==  "__main__" :       array = [ 22, 132, 4, 45, 12, 223 ] ;     n = len(array);           print(solve(array, n));           # This code is contributed by AnkitRai01



## C#

 // C# implementation of above approach using System;   class GFG {       static int []dp = new int [1024];   // Function to create mask for every number static int get_binary(int u) {     int ans = 0;     while (u > 0)           {         int rem = u % 10;         ans |= (1 << rem);         u /= 10;     }       return ans; }   // Recursion for Filling DP array static int recur(int u, int []array, int n) {     // Base Condition     if (u == 0)         return 0;     if (dp[u] != -1)         return dp[u];       for (int i = 0; i < n; i++)     {         int mask = get_binary(array[i]);           // Recurrence Relation         if ((mask | u) == u)         {             dp[u] = Math.Max(Math.Max(0,                     dp[u ^ mask]) + array[i], dp[u]);         }     }       return dp[u]; }   // Function to find Maximum Subset Sum static int solve(int []array, int n) {     // Initialize DP array     for (int i = 0; i < (1 << 10); i++)     {         dp[i] = -1;     }       int ans = 0;       // Iterate over all possible masks of 10 bit number     for (int i = 0; i < (1 << 10); i++)     {         ans = Math.Max(ans, recur(i, array, n));     }       return ans; }   // Driver Code static public void Main () {     int []array = { 22, 132, 4, 45, 12, 223 };     int n = array.Length;           Console.WriteLine (solve(array, n)); } }   // This code is contributed by ajit.

Output:

268

Time Complexity : O(N*(2^10))

Auxiliary Space: O(1024)

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 + memoization(top-down) because memoization method needs extra stack space of recursion calls.

Steps to solve this problem :

• Create a DP to store the solution of the subproblems.
• Initialize the DP  with base cases.
• Now Iterate over subproblems to get the value of current problem form previous computation of subproblems stored in DP.
• Create a variable ans to store the final result.
• Iterate over Dp and update ans.
• At last return and print ans.

Implementation :

## C++

 #include using namespace std;   int dp[1024];   // Function to create mask for every number int get_binary(int u) {     int ans = 0;     while (u) {         int rem = u % 10;         ans |= (1 << rem);         u /= 10;     }     return ans; }   // Function to find Maximum Subset Sum int solve(int array[], int n) {     // Initialize DP array     for (int i = 0; i < (1 << 10); i++) {         dp[i] = 0;     }       // Fill DP table using bottom-up approach     for (int i = 0; i < n; i++) {         int mask = get_binary(array[i]);         for (int j = (1 << 10) - 1; j >= 0; j--) {             if ((mask | j) == j) {                 dp[j] = max(dp[j], dp[j ^ mask] + array[i]);             }         }     }       // Find maximum sum from DP array     int ans = 0;     for (int i = 0; i < (1 << 10); i++) {         ans = max(ans, dp[i]);     }       return ans; }   // Driver Code int main() {     int array[] = { 22, 132, 4, 45, 12, 223 };     int n = sizeof(array) / sizeof(array[0]);       cout << solve(array, n); }

## Java

 import java.util.Arrays;   class GFG {   static int dp[] = new int[1024];     // Function to create mask for every number   static int get_binary(int u)   {     int ans = 0;     while (u != 0) {       int rem = u % 10;       ans |= (1 << rem);       u /= 10;     }     return ans;   }     // Function to find Maximum Subset Sum   static int solve(int array[], int n)   {     // Initialize DP array     Arrays.fill(dp, 0);       // Fill DP table using bottom-up approach     for (int i = 0; i < n; i++) {       int mask = get_binary(array[i]);       for (int j = (1 << 10) - 1; j >= 0; j--) {         if ((mask | j) == j) {           dp[j] = Math.max(dp[j], dp[j ^ mask]                            + array[i]);         }       }     }       // Find maximum sum from DP array     int ans = 0;     for (int i = 0; i < (1 << 10); i++) {       ans = Math.max(ans, dp[i]);     }       return ans;   }     // Driver Code   public static void main(String[] args)   {     int array[] = { 22, 132, 4, 45, 12, 223 };     int n = array.length;       System.out.println(solve(array, n));   } }

## Python3

 # Function to create mask for every number def get_binary(u):     ans = 0     while u:         rem = u % 10         ans |= (1 << rem)         u //= 10     return ans    # Function to find Maximum Subset Sum     def solve(array, n):     # Initialize DP array     dp = [0] * (1 << 10)       # Fill DP table using bottom-up approach     for i in range(n):         mask = get_binary(array[i])         for j in range((1 << 10) - 1, -1, -1):             if (mask | j) == j:                 dp[j] = max(dp[j], dp[j ^ mask] + array[i])       # Find maximum sum from DP array     ans = 0     for i in range(1 << 10):         ans = max(ans, dp[i])       return ans     # Driver Code array = [22, 132, 4, 45, 12, 223] n = len(array) print(solve(array, n))

## C#

 using System;   class Program {     static int[] dp = new int[1024];       // Function to create mask for every number     static int GetBinary(int u)     {         int ans = 0;         while (u != 0)         {             int rem = u % 10;             ans |= (1 << rem);             u /= 10;         }         return ans;     }       // Function to find Maximum Subset Sum     static int Solve(int[] array, int n)     {         // Initialize DP array         for (int i = 0; i < (1 << 10); i++)         {             dp[i] = 0;         }           // Fill DP table using bottom-up approach         for (int i = 0; i < n; i++)         {             int mask = GetBinary(array[i]);             for (int j = (1 << 10) - 1; j >= 0; j--)             {                 if ((mask | j) == j)                 {                     dp[j] = Math.Max(dp[j], dp[j ^ mask] + array[i]);                 }             }         }           // Find maximum sum from DP array         int ans = 0;         for (int i = 0; i < (1 << 10); i++)         {             ans = Math.Max(ans, dp[i]);         }           return ans;     }       // Driver Code     static void Main()     {         int[] array = { 22, 132, 4, 45, 12, 223 };         int n = array.Length;           Console.WriteLine(Solve(array, n));     } }

## Javascript

 // Function to create mask for every number function getBinary(u) {   let ans = 0;   while (u) {     let rem = u % 10;     ans |= (1 << rem);     u = Math.floor(u / 10);   }   return ans; }   // Function to find Maximum Subset Sum function solve(array, n) {   // Initialize DP array   let dp = new Array(1 << 10).fill(0);     // Fill DP table using bottom-up approach   for (let i = 0; i < n; i++) {     let mask = getBinary(array[i]);     for (let j = (1 << 10) - 1; j >= 0; j--) {       if ((mask | j) == j) {         dp[j] = Math.max(dp[j], dp[j ^ mask] + array[i]);       }     }   }     // Find maximum sum from DP array   let ans = 0;   for (let i = 0; i < 1 << 10; i++) {     ans = Math.max(ans, dp[i]);   }     return ans; }   // Driver Code let array = [22, 132, 4, 45, 12, 223]; let n = array.length; console.log(solve(array, n));

Output

268

Time Complexity : O(N*(2^10))

Auxiliary Space: O(2^10)

Previous
Next