Related Articles

Related Articles

Maximum subset sum such that no two elements in set have same digit in them
  • Difficulty Level : Hard
  • Last Updated : 12 Jun, 2019

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++



filter_none

edit
close

play_arrow

link
brightness_4
code

// 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);
}

chevron_right


Java

filter_none

edit
close

play_arrow

link
brightness_4
code

// 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..

chevron_right


Python3

filter_none

edit
close

play_arrow

link
brightness_4
code

# 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

chevron_right


C#

filter_none

edit
close

play_arrow

link
brightness_4
code

// 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.

chevron_right


Output:

268

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

Attention reader! Don’t stop learning now. Get hold of all the important DSA concepts with the DSA Self Paced Course at a student-friendly price and become industry ready.




My Personal Notes arrow_drop_up
Recommended Articles
Page :