Open In App

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 
 

 

Below is the implementation of the above approach: 
 




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




<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# 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 :

Implementation :




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




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




# 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))




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




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


Article Tags :