📌  相关文章
📜  最大子集总和,以使集合中没有两个元素具有相同的数字

📅  最后修改于: 2021-05-25 06:26:17             🧑  作者: Mango

给定N个元素的数组。找到具有最大总和的元素子集,以使子集中没有两个元素具有相同的数字。

例子:

  • 在这里,我们可以使用动态编程和位屏蔽来解决此问题。
  • 考虑每个数字的10位表示形式,如果该数字中存在与该位对应的数字,则每个位为1。
  • 现在,保持一个dp [i],该值存储最大的总和,该总和可以用集合中存在的所有这些数字来实现,对应于i的二进制表示中的位位置为1。
  • 对于从1到n的所有j,递归关系将采用dp [i] = max(dp [i],dp [i ^ mask] + a [j])的形式,使得掩码(a的10位表示) [j])满足我||遮罩= i。 (从那时起,只有我们才能确保满足i中所有可用的数字)。

下面是上述方法的实现:

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.


输出:
268

时间复杂度: O(N *(2 ^ 10))