给定大小为N的数组A ,我们的任务是找到最大子集的长度,以使子集中的所有元素都是成对的互质数,即对于x和y中的任意两个元素,其中x和y与gcd(x, y)等于1 。
注意:所有数组元素均<= 50。
例子:
Input: A = [2, 5, 2, 5, 2]
Output: 2
Explanation:
Largest subset satisfying the condition is: {2, 5}
Input: A = [2, 3, 13, 5, 14, 6, 7, 11]
Output: 6
天真的方法:
为了解决上述问题,我们必须生成所有子集,并针对每个子集检查给定条件是否成立。但是该方法需要O(N 2 * 2 N )时间,并且可以进一步优化。
下面是上述方法的实现:
C++
// C++ implementation to Find the length of the Largest
// subset such that all elements are Pairwise Coprime
#include
using namespace std;
// Function to find the largest subset possible
int largestSubset(int a[], int n)
{
int answer = 0;
// Iterate through all the subsets
for (int i = 1; i < (1 << n); i++) {
vector subset;
/* Check if jth bit in the counter is set */
for (int j = 0; j < n; j++) {
if (i & (1 << j))
subset.push_back(a[j]);
}
bool flag = true;
for (int j = 0; j < subset.size(); j++) {
for (int k = j + 1; k < subset.size(); k++) {
// Check if the gcd is not equal to 1
if (__gcd(subset[j], subset[k]) != 1)
flag = false;
}
}
if (flag == true)
// Update the answer with maximum value
answer = max(answer, (int)subset.size());
}
// Return the final result
return answer;
}
// Driver code
int main()
{
int A[] = { 2, 3, 13, 5, 14, 6, 7, 11 };
int N = sizeof(A) / sizeof(A[0]);
cout << largestSubset(A, N);
return 0;
}
Java
// Java implementation to find the length
// of the largest subset such that all
// elements are Pairwise Coprime
import java.util.*;
class GFG{
static int gcd(int a, int b)
{
// Everything divides 0
if (a == 0)
return b;
if (b == 0)
return a;
// Base case
if (a == b)
return a;
// a is greater
if (a > b)
return gcd(a - b, b);
return gcd(a, b - a);
}
// Function to find the largest subset possible
static int largestSubset(int a[], int n)
{
int answer = 0;
// Iterate through all the subsets
for(int i = 1; i < (1 << n); i++)
{
Vector subset = new Vector();
// Check if jth bit in the counter is set
for(int j = 0; j < n; j++)
{
if ((i & (1 << j)) != 0)
subset.add(a[j]);
}
boolean flag = true;
for(int j = 0; j < subset.size(); j++)
{
for(int k = j + 1; k < subset.size(); k++)
{
// Check if the gcd is not equal to 1
if (gcd((int)subset.get(j),
(int) subset.get(k)) != 1)
flag = false;
}
}
if (flag == true)
// Update the answer with maximum value
answer = Math.max(answer,
(int)subset.size());
}
// Return the final result
return answer;
}
// Driver code
public static void main(String args[])
{
int A[] = { 2, 3, 13, 5, 14, 6, 7, 11 };
int N = A.length;
System.out.println(largestSubset(A, N));
}
}
// This code is contributed by Stream_Cipher
Python3
# Python3 implementation to Find
# the length of the Largest subset
# such that all elements are Pairwise Coprime
import math
# Function to find the largest subset possible
def largestSubset(a, n):
answer = 0
# Iterate through all the subsets
for i in range(1, (1 << n)):
subset = []
# Check if jth bit in the counter is set
for j in range(0, n):
if (i & (1 << j)):
subset.insert(j, a[j])
flag = True
for j in range(0, len(subset)):
for k in range(j + 1, len(subset)):
# Check if the gcd is not equal to 1
if (math.gcd(subset[j], subset[k]) != 1) :
flag = False
if (flag == True):
# Update the answer with maximum value
answer = max(answer, len(subset))
# Return the final result
return answer
# Driver code
A = [ 2, 3, 13, 5, 14, 6, 7, 11 ]
N = len(A)
print(largestSubset(A, N))
# This code is contributed by Sanjit_Prasad
C#
// C# implementation to Find the length
// of the largest subset such that all
// elements are Pairwise Coprime
using System;
using System.Collections.Generic;
class GFG{
static int gcd(int a, int b)
{
// Everything divides 0
if (a == 0)
return b;
if (b == 0)
return a;
// base case
if (a == b)
return a;
// a is greater
if (a > b)
return gcd(a - b, b);
return gcd(a, b - a);
}
// Function to find the largest subset possible
static int largestSubset(int []a, int n)
{
int answer = 0;
// Iterate through all the subsets
for(int i = 1; i < (1 << n); i++)
{
List subset = new List();
// Check if jth bit in the counter is set
for(int j = 0; j < n; j++)
{
if ((i & (1 << j)) != 0)
subset.Add(a[j]);
}
int flag = 1;
for(int j = 0; j < subset.Count; j++)
{
for(int k = j + 1; k < subset.Count; k++)
{
// Check if the gcd is not equal to 1
if (gcd((int)subset[j],
(int) subset[k]) != 1)
flag = 0;
}
}
if (flag == 1)
// Update the answer with maximum value
answer = Math.Max(answer,
(int)subset.Count);
}
// Return the final result
return answer;
}
// Driver code
public static void Main()
{
int []A = { 2, 3, 13, 5, 14, 6, 7, 11 };
int N = A.Length;
Console.WriteLine(largestSubset(A, N));
}
}
// This code is contributed by Stream_Cipher
C++
// C++ implementation to Find the length of the Largest
// subset such that all elements are Pairwise Coprime
#include
using namespace std;
// Dynamic programming table
int dp[5000][(1 << 10) + 5];
// Function to obtain the mask for any integer
int getmask(int val)
{
int mask = 0;
// List of prime numbers till 50
int prime[15] = { 2, 3, 5, 7, 11, 13, 17, 19,
23, 29, 31, 37, 41, 43, 47 };
// Iterate through all prime numbers to obtain the mask
for (int i = 0; i < 15; i++) {
if (val % prime[i] == 0) {
// Set this prime's bit ON in the mask
mask = mask | (1 << i);
}
}
// Return the mask value
return mask;
}
// Function to count the number of ways
int calculate(int pos, int mask,
int a[], int n)
{
if (pos == n || mask == (1 << n - 1))
return 0;
// Check if subproblem has been solved
if (dp[pos][mask] != -1)
return dp[pos][mask];
int size = 0;
// Excluding current element in the subset
size = max(size, calculate(pos + 1, mask, a, n));
// Check if there are no common prime factors
// then only this element can be included
if ((getmask(a[pos]) & mask) == 0) {
// Calculate the new mask if this element is included
int new_mask = (mask | (getmask(a[pos])));
size = max(size, 1 + calculate(pos + 1, new_mask, a, n));
}
// Store and return the answer
return dp[pos][mask] = size;
}
// Function to find the count of
// subarray with all digits unique
int largestSubset(int a[], int n)
{
// Intializing dp
memset(dp, -1, sizeof(dp));
return calculate(0, 0, a, n);
}
// Driver code
int main()
{
int A[] = { 2, 3, 13, 5, 14, 6, 7, 11 };
int N = sizeof(A) / sizeof(A[0]);
cout << largestSubset(A, N);
return 0;
}
Java
// Java implementation to find the length
// of the largest subset such that all
// elements are Pairwise Coprime
import java.util.*;
class GFG{
// Dynamic programming table
static int dp[][] = new int [5000][1029];
// Function to obtain the mask for any integer
static int getmask(int val)
{
int mask = 0;
// List of prime numbers till 50
int prime[] = { 2, 3, 5, 7, 11, 13, 17, 19,
23, 29, 31, 37, 41, 43, 47 };
// Iterate through all prime numbers
// to obtain the mask
for(int i = 0; i < 15; i++)
{
if (val % prime[i] == 0)
{
// Set this prime's bit ON in the mask
mask = mask | (1 << i);
}
}
// Return the mask value
return mask;
}
// Function to count the number of ways
static int calculate(int pos, int mask,
int a[], int n)
{
if (pos == n ||
mask == (int)(1 << n - 1))
return 0;
// Check if subproblem has been solved
if (dp[pos][mask] != -1)
return dp[pos][mask];
int size = 0;
// Excluding current element in the subset
size = Math.max(size, calculate(pos + 1,
mask, a, n));
// Check if there are no common prime factors
// then only this element can be included
if ((getmask(a[pos]) & mask) == 0)
{
// Calculate the new mask if this
// element is included
int new_mask = (mask | (getmask(a[pos])));
size = Math.max(size, 1 + calculate(pos + 1,
new_mask,
a, n));
}
// Store and return the answer
return dp[pos][mask] = size;
}
// Function to find the count of
// subarray with all digits unique
static int largestSubset(int a[], int n)
{
for(int i = 0; i < 5000; i++)
Arrays.fill(dp[i], -1);
return calculate(0, 0, a, n);
}
// Driver code
public static void main(String args[])
{
int A[] = { 2, 3, 13, 5, 14, 6, 7, 11 };
int N = A.length;
System.out.println(largestSubset(A, N));
}
}
// This code is contributed by Stream_Cipher
Python
# Python implementation to find the
# length of the Largest subset such
# that all elements are Pairwise Coprime
# Dynamic programming table
dp = [[-1] * ((1 << 10) + 5)] * 5000
# Function to obtain the mask for any integer
def getmask(val):
mask = 0
# List of prime numbers till 50
prime = [ 2, 3, 5, 7, 11, 13, 17, 19,
23, 29, 31, 37, 41, 43, 47 ]
# Iterate through all prime numbers
# to obtain the mask
for i in range(1, 15):
if val % prime[i] == 0:
# Set this prime's bit ON in the mask
mask = mask | (1 << i)
# Return the mask value
return mask
# Function to count the number of ways
def calculate(pos, mask, a, n):
if ((pos == n) or (mask == (1 << n - 1))):
return 0
# Check if subproblem has been solved
if dp[pos][mask] != -1:
return dp[pos][mask]
size = 0
# Excluding current element in the subset
size = max(size, calculate(pos + 1,
mask, a, n))
# Check if there are no common prime factors
# then only this element can be included
if (getmask(a[pos]) & mask) == 0:
# Calculate the new mask if this
# element is included
new_mask = (mask | (getmask(a[pos])))
size = max(size, 1 + calculate(pos + 1,
new_mask,
a, n))
# Store and return the answer
dp[pos][mask] = size
return dp[pos][mask]
# Function to find the count of
# subarray with all digits unique
def largestSubset(A, n):
return calculate(0, 0, A, n);
# Driver code
A = [ 2, 3, 13, 5, 14, 6, 7, 11 ]
N = len(A)
print(largestSubset(A, N))
# This code is contributed by Stream_Cipher
C#
// C# implementation to find the length
// of the largest subset such that all
// elements are Pairwise Coprime
using System;
class GFG{
// Dynamic programming table
static int [,] dp = new int [5000, 1029];
// Function to obtain the mask for any integer
static int getmask(int val)
{
int mask = 0;
// List of prime numbers till 50
int []prime = { 2, 3, 5, 7, 11, 13, 17, 19,
23, 29, 31, 37, 41, 43, 47 };
// Iterate through all prime
// numbers to obtain the mask
for(int i = 0; i < 15; i++)
{
if (val % prime[i] == 0)
{
// Set this prime's bit ON in the mask
mask = mask | (1 << i);
}
}
// Return the mask value
return mask;
}
// Function to count the number of ways
static int calculate(int pos, int mask,
int []a, int n)
{
if (pos == n ||
mask == (int)(1 << n - 1))
return 0;
// Check if subproblem has been solved
if (dp[pos, mask] != -1)
return dp[pos, mask];
int size = 0;
// Excluding current element in the subset
size = Math.Max(size, calculate(pos + 1,
mask, a, n));
// Check if there are no common prime factors
// then only this element can be included
if ((getmask(a[pos]) & mask) == 0)
{
// Calculate the new mask if
// this element is included
int new_mask = (mask | (getmask(a[pos])));
size = Math.Max(size, 1 + calculate(pos + 1,
new_mask,
a, n));
}
// Store and return the answer
return dp[pos, mask] = size;
}
// Function to find the count of
// subarray with all digits unique
static int largestSubset(int []a, int n)
{
for(int i = 0; i < 5000; i++)
{
for(int j = 0; j < 1029; j++)
dp[i, j] = -1;
}
return calculate(0, 0, a, n);
}
// Driver code
public static void Main()
{
int []A = { 2, 3, 13, 5, 14, 6, 7, 11 };
int N = A.Length;
Console.WriteLine(largestSubset(A, N));
}
}
// This code is contributed by Stream_Cipher
输出:
6
高效方法:
可以优化上述方法,并且该方法取决于以下事实:前50个自然数中只有15个素数。因此,数组中的所有数字仅在这15个数字中具有素数。我们将使用位屏蔽和动态编程来优化该问题。
- 由于仅存在15个质数,因此考虑每个质数的15位表示形式,如果该质数的索引是该数的因子,则每个位为1。我们将通过0索引对素数进行索引,这意味着2在索引1的第0个位置3处,依此类推。
- 整数变量“ mask ”表示子集中已经出现的主要因子。如果在掩码中设置了第i个位,则表示存在第i个素因数,否则没有发生。
- 在递归关系的每个步骤中,元素可以包含在子集中,也可以不包含。如果该元素未包含在子数组中,则只需移至下一个索引。如果包含它,则通过将与当前元素的质数因子相对应的所有位设置为ON来更改掩码。如果当前元素的所有主要因素以前均未发生,则只能包括该元素。
- 仅当掩码中与当前元素的数字相对应的位为OFF时,才能满足此条件。
如果我们绘制完整的递归树,则可以观察到正在解决的许多子问题一次又一次地发生。因此,我们使用表dp [] [],使得对于每个索引dp [i] [j],i是元素在数组中的位置,而j是掩码。
下面是上述方法的实现:
C++
// C++ implementation to Find the length of the Largest
// subset such that all elements are Pairwise Coprime
#include
using namespace std;
// Dynamic programming table
int dp[5000][(1 << 10) + 5];
// Function to obtain the mask for any integer
int getmask(int val)
{
int mask = 0;
// List of prime numbers till 50
int prime[15] = { 2, 3, 5, 7, 11, 13, 17, 19,
23, 29, 31, 37, 41, 43, 47 };
// Iterate through all prime numbers to obtain the mask
for (int i = 0; i < 15; i++) {
if (val % prime[i] == 0) {
// Set this prime's bit ON in the mask
mask = mask | (1 << i);
}
}
// Return the mask value
return mask;
}
// Function to count the number of ways
int calculate(int pos, int mask,
int a[], int n)
{
if (pos == n || mask == (1 << n - 1))
return 0;
// Check if subproblem has been solved
if (dp[pos][mask] != -1)
return dp[pos][mask];
int size = 0;
// Excluding current element in the subset
size = max(size, calculate(pos + 1, mask, a, n));
// Check if there are no common prime factors
// then only this element can be included
if ((getmask(a[pos]) & mask) == 0) {
// Calculate the new mask if this element is included
int new_mask = (mask | (getmask(a[pos])));
size = max(size, 1 + calculate(pos + 1, new_mask, a, n));
}
// Store and return the answer
return dp[pos][mask] = size;
}
// Function to find the count of
// subarray with all digits unique
int largestSubset(int a[], int n)
{
// Intializing dp
memset(dp, -1, sizeof(dp));
return calculate(0, 0, a, n);
}
// Driver code
int main()
{
int A[] = { 2, 3, 13, 5, 14, 6, 7, 11 };
int N = sizeof(A) / sizeof(A[0]);
cout << largestSubset(A, N);
return 0;
}
Java
// Java implementation to find the length
// of the largest subset such that all
// elements are Pairwise Coprime
import java.util.*;
class GFG{
// Dynamic programming table
static int dp[][] = new int [5000][1029];
// Function to obtain the mask for any integer
static int getmask(int val)
{
int mask = 0;
// List of prime numbers till 50
int prime[] = { 2, 3, 5, 7, 11, 13, 17, 19,
23, 29, 31, 37, 41, 43, 47 };
// Iterate through all prime numbers
// to obtain the mask
for(int i = 0; i < 15; i++)
{
if (val % prime[i] == 0)
{
// Set this prime's bit ON in the mask
mask = mask | (1 << i);
}
}
// Return the mask value
return mask;
}
// Function to count the number of ways
static int calculate(int pos, int mask,
int a[], int n)
{
if (pos == n ||
mask == (int)(1 << n - 1))
return 0;
// Check if subproblem has been solved
if (dp[pos][mask] != -1)
return dp[pos][mask];
int size = 0;
// Excluding current element in the subset
size = Math.max(size, calculate(pos + 1,
mask, a, n));
// Check if there are no common prime factors
// then only this element can be included
if ((getmask(a[pos]) & mask) == 0)
{
// Calculate the new mask if this
// element is included
int new_mask = (mask | (getmask(a[pos])));
size = Math.max(size, 1 + calculate(pos + 1,
new_mask,
a, n));
}
// Store and return the answer
return dp[pos][mask] = size;
}
// Function to find the count of
// subarray with all digits unique
static int largestSubset(int a[], int n)
{
for(int i = 0; i < 5000; i++)
Arrays.fill(dp[i], -1);
return calculate(0, 0, a, n);
}
// Driver code
public static void main(String args[])
{
int A[] = { 2, 3, 13, 5, 14, 6, 7, 11 };
int N = A.length;
System.out.println(largestSubset(A, N));
}
}
// This code is contributed by Stream_Cipher
Python
# Python implementation to find the
# length of the Largest subset such
# that all elements are Pairwise Coprime
# Dynamic programming table
dp = [[-1] * ((1 << 10) + 5)] * 5000
# Function to obtain the mask for any integer
def getmask(val):
mask = 0
# List of prime numbers till 50
prime = [ 2, 3, 5, 7, 11, 13, 17, 19,
23, 29, 31, 37, 41, 43, 47 ]
# Iterate through all prime numbers
# to obtain the mask
for i in range(1, 15):
if val % prime[i] == 0:
# Set this prime's bit ON in the mask
mask = mask | (1 << i)
# Return the mask value
return mask
# Function to count the number of ways
def calculate(pos, mask, a, n):
if ((pos == n) or (mask == (1 << n - 1))):
return 0
# Check if subproblem has been solved
if dp[pos][mask] != -1:
return dp[pos][mask]
size = 0
# Excluding current element in the subset
size = max(size, calculate(pos + 1,
mask, a, n))
# Check if there are no common prime factors
# then only this element can be included
if (getmask(a[pos]) & mask) == 0:
# Calculate the new mask if this
# element is included
new_mask = (mask | (getmask(a[pos])))
size = max(size, 1 + calculate(pos + 1,
new_mask,
a, n))
# Store and return the answer
dp[pos][mask] = size
return dp[pos][mask]
# Function to find the count of
# subarray with all digits unique
def largestSubset(A, n):
return calculate(0, 0, A, n);
# Driver code
A = [ 2, 3, 13, 5, 14, 6, 7, 11 ]
N = len(A)
print(largestSubset(A, N))
# This code is contributed by Stream_Cipher
C#
// C# implementation to find the length
// of the largest subset such that all
// elements are Pairwise Coprime
using System;
class GFG{
// Dynamic programming table
static int [,] dp = new int [5000, 1029];
// Function to obtain the mask for any integer
static int getmask(int val)
{
int mask = 0;
// List of prime numbers till 50
int []prime = { 2, 3, 5, 7, 11, 13, 17, 19,
23, 29, 31, 37, 41, 43, 47 };
// Iterate through all prime
// numbers to obtain the mask
for(int i = 0; i < 15; i++)
{
if (val % prime[i] == 0)
{
// Set this prime's bit ON in the mask
mask = mask | (1 << i);
}
}
// Return the mask value
return mask;
}
// Function to count the number of ways
static int calculate(int pos, int mask,
int []a, int n)
{
if (pos == n ||
mask == (int)(1 << n - 1))
return 0;
// Check if subproblem has been solved
if (dp[pos, mask] != -1)
return dp[pos, mask];
int size = 0;
// Excluding current element in the subset
size = Math.Max(size, calculate(pos + 1,
mask, a, n));
// Check if there are no common prime factors
// then only this element can be included
if ((getmask(a[pos]) & mask) == 0)
{
// Calculate the new mask if
// this element is included
int new_mask = (mask | (getmask(a[pos])));
size = Math.Max(size, 1 + calculate(pos + 1,
new_mask,
a, n));
}
// Store and return the answer
return dp[pos, mask] = size;
}
// Function to find the count of
// subarray with all digits unique
static int largestSubset(int []a, int n)
{
for(int i = 0; i < 5000; i++)
{
for(int j = 0; j < 1029; j++)
dp[i, j] = -1;
}
return calculate(0, 0, a, n);
}
// Driver code
public static void Main()
{
int []A = { 2, 3, 13, 5, 14, 6, 7, 11 };
int N = A.Length;
Console.WriteLine(largestSubset(A, N));
}
}
// This code is contributed by Stream_Cipher
输出:
6
时间复杂度: O(N * 15 * 2 15 )