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 <bits/stdc++.h>using namespace std;int dp[1024]; // Function to create mask for every numberint get_binary(int u){ int ans = 0; while (u) { int rem = u % 10; ans |= (1 << rem); u /= 10; } return ans;} // Recursion for Filling DP arrayint 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 Sumint 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 Codeint 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 approachimport java.io.*;class GFG{ static int []dp = new int [1024];// Function to create mask for every numberstatic 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 arraystatic 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 Sumstatic 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 Codestatic 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 |
Javascript
<script> // Javascript implementation of above approach let dp = new Array(1024); dp.fill(-1); // Function to create mask for every number function get_binary(u) { let ans = 0; while (u > 0) { let rem = u % 10; ans |= (1 << rem); u = parseInt(u / 10, 10); } return ans; } // Recursion for Filling DP array function recur(u, array, n) { // Base Condition if (u == 0) return 0; if (dp[u] != -1) return dp[u]; for (let i = 0; i < n; i++) { let 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 function solve(array, n) { // Initialize DP array for (let i = 0; i < (1 << 10); i++) { dp[i] = -1; } let ans = 0; // Iterate over all possible masks of 10 bit number for (let i = 0; i < (1 << 10); i++) { ans = Math.max(ans, recur(i, array, n)); } return ans; } let array = [ 22, 132, 4, 45, 12, 223 ]; let n = array.length; document.write(solve(array, n));</script> |
C#
// C# implementation of above approachusing System;class GFG{ static int []dp = new int [1024];// Function to create mask for every numberstatic 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 arraystatic 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 Sumstatic 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 Codestatic 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. |
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 <bits/stdc++.h>using namespace std;int dp[1024];// Function to create mask for every numberint 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 Sumint 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 Codeint 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 numberdef get_binary(u): ans = 0 while u: rem = u % 10 ans |= (1 << rem) u //= 10 return ans # Function to find Maximum Subset Sumdef 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 Codearray = [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 numberfunction 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 Sumfunction 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 Codelet 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)
Ready to dive in? Explore our Free Demo Content and join our DSA course, trusted by over 100,000 neveropen!
