给定一个长度为N的数组arr和一个整数K ,任务是计算长度最多为K的可能子序列的数量,这些子序列包含来自数组的不同素数元素。
例子:
Input: arr[] = {1, 2, 2, 3, 3, 4, 5}, N = 7, K = 3
Output: 18
Explanation: {}, {2}, {2}, {3}, {3}, {5}, {2, 3}, {2, 3}, {2, 3}, {2, 3}, {2, 5}, {2, 5}, {3, 5}, {3, 5}, {2, 3, 5}, {2, 3, 5}, {2, 3, 5} and {2, 3, 5} are the subsequences.
Input arr[] = {2, 4, 6, 7, 3, 9, 11, 5}, N = 8, K = 3
Output: 26
方法:
使用埃拉托色尼筛法,预先计算并存储所有质数。计算并存储给定数组中每个素数的频率。使用动态规划方法,计算长度为 2 到K的子序列的数量。通过为每个dp[i]添加长度 2 到K的可能不同组合来不断更新ans 。计算后,将所有质数的频率加 1 作为长度为 1 和 0 的子序列。 ans的最终值给出了所需的结果。
下面是上述方法的实现:
C++
// C++ Program to find the
// count of distinct prime
// subsequences at most of
// of length K from a given array
#include
using namespace std;
bool prime[100001];
void SieveOfEratosthenes()
{
// Initialize all indices as true
memset(prime, true, sizeof(prime));
prime[0] = prime[1] = false;
// A value in prime[i] will finally be
// false if i is not a prime, else true
for (int p = 2; p * p <= 100000; p++) {
// If prime[p] is true,
// then it is a prime
if (prime[p] == true) {
// Update all multiples of p
// as false, i.e. non-prime
for (int i = p * p;
i <= 100000;
i += p)
prime[i] = false;
}
}
}
// Returns number of subsequences
// of maximum length k and
// contains distinct primes
int distinctPrimeSubSeq(
int a[],
int n, int k)
{
SieveOfEratosthenes();
// Store the primes in
// the given array
vector primes;
for (int i = 0; i < n; i++) {
if (prime[a[i]])
primes.push_back(a[i]);
}
int l = primes.size();
// Sort the primes
sort(primes.begin(),
primes.end());
// Store the frequencies
// of all the
// distinct primes
vector b;
vector dp;
int sum = 0;
for (int i = 0; i < l;) {
int count = 1, x = a[i];
i++;
while (i < l && a[i] == x) {
count++;
i++;
}
// Store the frequency
// of primes
b.push_back(count);
dp.push_back(count);
// Store the sum of all
// frequencies
sum += count;
}
// Store the length of
// subsequence at every
// instant
int of_length = 2;
int len = dp.size();
int ans = 0;
while (of_length <= k) {
// Store the frequency
int freq = 0;
// Store the previous
// count of updated DP
int prev = 0;
for (int i = 0; i < (len - 1); i++) {
freq += dp[i];
int j = sum - freq;
// Calculate total subsequences
// of current of_length
int subseq = b[i] * j;
// Add the number of
// subsequences to the answer
ans += subseq;
// Update the value in dp[i]
dp[i] = subseq;
// Store the updated dp[i]
prev += dp[i];
}
len--;
sum = prev;
of_length++;
}
ans += (l + 1);
return ans;
}
// Driver Code
int main()
{
int a[] = { 1, 2, 2, 3, 3, 4, 5 };
int n = sizeof(a) / sizeof(int);
int k = 3;
cout << distinctPrimeSubSeq(a, n, k);
return 0;
}
Java
// Java Program to find the
// count of distinct prime
// subsequences at most of
// of length K from a given array
import java.util.*;
class GFG{
static boolean []prime =
new boolean[100001];
static void SieveOfEratosthenes()
{
// Initialize all indices as true
for (int i = 0; i < prime.length; i++)
prime[i] = true;
prime[0] = prime[1] = false;
// A value in prime[i] will finally
// be false if i is not a prime,
// else true
for (int p = 2; p * p < 100000; p++)
{
// If prime[p] is true,
// then it is a prime
if (prime[p] == true)
{
// Update all multiples of p
// as false, i.e. non-prime
for (int i = p * p;
i <= 100000; i += p)
prime[i] = false;
}
}
}
// Returns number of subsequences
// of maximum length k and
// contains distinct primes
static int distinctPrimeSubSeq(int a[],
int n,
int k)
{
SieveOfEratosthenes();
// Store the primes in
// the given array
Vector primes =
new Vector<>();
for (int i = 0; i < n; i++)
{
if (prime[a[i]])
primes.add(a[i]);
}
int l = primes.size();
// Sort the primes
Collections.sort(primes);
// Store the frequencies
// of all the
// distinct primes
Vector b =
new Vector<>();
Vector dp =
new Vector<>();
int sum = 0;
for (int i = 0; i < l;)
{
int count = 1, x = a[i];
i++;
while (i < l && a[i] == x)
{
count++;
i++;
}
// Store the frequency
// of primes
b.add(count);
dp.add(count);
// Store the sum of all
// frequencies
sum += count;
}
// Store the length of
// subsequence at every
// instant
int of_length = 2;
int len = dp.size();
int ans = 0;
while (of_length < k)
{
// Store the frequency
int freq = 0;
// Store the previous
// count of updated DP
int prev = 0;
for (int i = 0;
i < (len - 1); i++)
{
freq += dp.elementAt(i);
int j = sum - freq;
// Calculate total subsequences
// of current of_length
int subseq = b.elementAt(i) * j;
// Add the number of
// subsequences to the answer
ans += subseq;
// Update the value in dp[i]
dp.add(i, subseq);
// Store the updated dp[i]
prev += dp.elementAt(i);
}
len--;
sum = prev;
of_length++;
}
ans += (l + 3);
return ans;
}
// Driver Code
public static void main(String[] args)
{
int a[] = {1, 2, 2, 3, 3, 4, 5};
int n = a.length;
int k = 3;
System.out.print(distinctPrimeSubSeq(a, n, k));
}
}
// This code is contributed by Princi Singh
Python3
# Python3 Program to find the
# count of distinct prime
# subsequences at most of
# of length K from a given array
prime = [True] * 1000000
def SieveOfEratosthenes():
global prime
prime[0] = prime[1] = False
# A value in prime[i] will
# finally be false if i is
# not a prime, else true
p = 2
while p * p <= 100000:
# If prime[p] is true,
# then it is a prime
if (prime[p] == True):
# Update all multiples of p
# as false, i.e. non-prime
for i in range(p * p,
100001, p):
prime[i] = False
p += 1
# Returns number of subsequences
# of maximum length k and
# contains distinct primes
def distinctPrimeSubSeq(a,
n, k):
SieveOfEratosthenes()
# Store the primes in
# the given array
primes = []
for i in range(n):
if (prime[a[i]]):
primes.append(a[i])
l = len(primes)
# Sort the primes
primes.sort()
# Store the frequencies
# of all the
# distinct primes
b = []
dp = []
sum = 0
i = 0
while i < l:
count = 1
x = a[i]
i += 1
while (i < l and
a[i] == x):
count += 1
i += 1
# Store the frequency
# of primes
b.append(count)
dp.append(count)
# Store the sum of all
# frequencies
sum += count
# Store the length of
# subsequence at every
# instant
of_length = 2
leng = len(dp)
ans = 0
while (of_length <= k):
# Store the frequency
freq = 0
# Store the previous
# count of updated DP
prev = 0
for i in range(leng - 1):
freq += dp[i]
j = sum - freq
# Calculate total subsequences
# of current of_length
subseq = b[i] * j
# Add the number of
# subsequences to the answer
ans += subseq
# Update the value in dp[i]
dp[i] = subseq
# Store the updated dp[i]
prev += dp[i]
leng -= 1
sum = prev
of_length += 1
ans += (l + 1)
return ans
# Driver Code
if __name__ == "__main__":
a = [1, 2, 2,
3, 3, 4, 5]
n = len(a)
k = 3
print(distinctPrimeSubSeq(a, n, k))
# This code is contributed by Chitranayal
C#
// C# Program to find the
// count of distinct prime
// subsequences at most of
// of length K from a given array
using System;
using System.Collections.Generic;
class GFG{
static bool []prime =
new bool[100001];
static void SieveOfEratosthenes()
{
// Initialize all indices as true
for (int i = 0; i < prime.Length; i++)
prime[i] = true;
prime[0] = prime[1] = false;
// A value in prime[i] will finally
// be false if i is not a prime,
// else true
for (int p = 2; p * p < 100000; p++)
{
// If prime[p] is true,
// then it is a prime
if (prime[p] == true)
{
// Update all multiples of p
// as false, i.e. non-prime
for (int i = p * p;
i <= 100000; i += p)
prime[i] = false;
}
}
}
// Returns number of subsequences
// of maximum length k and
// contains distinct primes
static int distinctPrimeSubSeq(int []a,
int n,
int k)
{
SieveOfEratosthenes();
// Store the primes in
// the given array
List primes = new List();
for (int i = 0; i < n; i++)
{
if (prime[a[i]])
primes.Add(a[i]);
}
int l = primes.Count;
// Sort the primes
primes.Sort();
// Store the frequencies
// of all the
// distinct primes
List b = new List();
List dp = new List();
int sum = 0;
for (int i = 0; i < l;)
{
int count = 1, x = a[i];
i++;
while (i < l && a[i] == x)
{
count++;
i++;
}
// Store the frequency
// of primes
b.Add(count);
dp.Add(count);
// Store the sum of all
// frequencies
sum += count;
}
// Store the length of
// subsequence at every
// instant
int of_length = 2;
int len = dp.Count;
int ans = 0;
while (of_length <= k)
{
// Store the frequency
int freq = 0;
// Store the previous
// count of updated DP
int prev = 0;
for (int i = 0;
i < (len ); i++)
{
freq += dp[i];
int j = sum - freq;
// Calculate total subsequences
// of current of_length
int subseq = b[i] * j;
// Add the number of
// subsequences to the answer
ans += subseq;
// Update the value in dp[i]
dp[i] = subseq;
// Store the updated dp[i]
prev += dp[i];
}
len--;
sum = prev;
of_length++;
}
ans += (l + 1);
return ans;
}
// Driver Code
public static void Main(String[] args)
{
int []a = {1, 2, 2, 3, 3, 4, 5};
int n = a.Length;
int k = 3;
Console.Write(distinctPrimeSubSeq(a, n, k));
}
}
// This code is contributed by Princi Singh
Javascript
输出:
18
时间复杂度: O(K*(不同质数))