给定一个包含 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 的位位置。
- 循环关系的形式为dp[i] = max(dp[i], dp[i^mask] + a[j]) ,对于从 1 到 n 的所有 j 使得掩码(a 的 10 位表示) [j]) 满足 i ||面具 = 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.
Javascript
输出:
268
时间复杂度: O(N*(2^10))
如果您希望与专家一起参加现场课程,请参阅DSA 现场工作专业课程和学生竞争性编程现场课程。