Maximum subset sum such that no two elements in set have same digit in them
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 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. |
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> |
Output:
268
Time Complexity : O(N*(2^10))
Auxiliary Space: O(1024)