给定N个元素的数组。找到具有最大总和的元素子集,以使子集中没有两个元素具有相同的数字。
例子:
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
- 在这里,我们可以使用动态编程和位屏蔽来解决此问题。
- 考虑每个数字的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))