📌  相关文章
📜  最长子序列,使得子序列中的每个元素都是通过将前一个元素与素数相乘而形成的

📅  最后修改于: 2021-10-27 08:46:06             🧑  作者: Mango

给定N 个整数的排序数组。任务是找到最长的子序列,使得子序列中的每个元素都可以通过将任何素数乘以子序列中的前一个元素来达到。
注意:A[i] <= 10 5

例子:

方法:这个问题可以通过使用预先存储素数直到数组中的最大数和使用基本的动态规划来解决。可以按照以下步骤解决上述问题:

  • 最初,它们将所有素数存储在任何数据结构中。
  • 散列散列图中数字的索引。
  • 创建一个大小为 N 的 dp[],并在每个地方用 1 初始化它,因为最长的子序列可能只有 1。 dp[i]表示以a[i]为起始元素可以形成的最长子序列的长度。
  • 从 n-2 开始迭代,对每个数乘以所有素数,直到超过 a[n-1] 并执行以下操作。
  • 将数字 a[i] 与素数相乘得到 x。如果 x 存在于散列映射中,那么循环将是dp[i] = max(dp[i], 1 + dp[hash[x]])
  • 最后,在 dp[] 数组中迭代并找到最大值作为我们的答案。

下面是上述方法的实现:

C++
// C++ program to implement the
// above approach
#include 
using namespace std;
 
// Function to pre-store primes
void SieveOfEratosthenes(int MAX, vector& primes)
{
    bool prime[MAX + 1];
    memset(prime, true, sizeof(prime));
 
    // Sieve method to check if prime or not
    for (long long p = 2; p * p <= MAX; p++) {
        if (prime[p] == true) {
            // Multiples
            for (long long i = p * p; i <= MAX; i += p)
                prime[i] = false;
        }
    }
 
    // Pre-store all the primes
    for (long long i = 2; i <= MAX; i++) {
        if (prime[i])
            primes.push_back(i);
    }
}
 
// Function to find the longest subsequence
int findLongest(int A[], int n)
{
    // Hash map
    unordered_map mpp;
    vector primes;
 
    // Call the function to pre-store the primes
    SieveOfEratosthenes(A[n - 1], primes);
 
    int dp[n];
    memset(dp, 0, sizeof dp);
 
    // Initialize last element with 1
    // as that is the longest possible
    dp[n - 1] = 1;
    mpp[A[n - 1]] = n - 1;
 
    // Iterate from the back and find the longest
    for (int i = n - 2; i >= 0; i--) {
 
        // Get the number
        int num = A[i];
 
        // Initialize dp[i] as 1
        // as the element will only me in
        // the subsequence .
        dp[i] = 1;
        int maxi = 0;
 
        // Iterate in all the primes and
        // multiply to get the next element
        for (auto it : primes) {
 
            // Next element if multiplied with it
            int xx = num * it;
 
            // If exceeds the last element
            // then break
            if (xx > A[n - 1])
                break;
 
            // If the number is there in the array
            else if (mpp[xx] != 0) {
                // Get the maximum most element
                dp[i] = max(dp[i], 1 + dp[mpp[xx]]);
            }
        }
        // Hash the element
        mpp[A[i]] = i;
    }
    int ans = 1;
 
    // Find the longest
    for (int i = 0; i < n; i++) {
        ans = max(ans, dp[i]);
    }
 
    return ans;
}
// Driver Code
int main()
{
    int a[] = { 1, 2, 5, 6, 12, 35, 60, 385 };
    int n = sizeof(a) / sizeof(a[0]);
    cout << findLongest(a, n);
}


Java
// Java program to implement the
// above approach
import java.util.HashMap;
import java.util.Vector;
 
class GFG
{
 
    // Function to pre-store primes
    public static void SieveOfEratosthenes(int MAX,
                            Vector primes)
    {
        boolean[] prime = new boolean[MAX + 1];
        for (int i = 0; i < MAX + 1; i++)
            prime[i] = true;
 
        // Sieve method to check if prime or not
        for (int p = 2; p * p <= MAX; p++)
        {
            if (prime[p] == true)
            {
                // Multiples
                for (int i = p * p; i <= MAX; i += p)
                    prime[i] = false;
            }
        }
 
        // Pre-store all the primes
        for (int i = 2; i <= MAX; i++)
        {
            if (prime[i])
                primes.add(i);
        }
    }
 
    // Function to find the intest subsequence
    public static int findLongest(int[] A, int n)
    {
 
        // Hash map
        HashMap mpp = new HashMap<>();
        Vector primes = new Vector<>();
 
        // Call the function to pre-store the primes
        SieveOfEratosthenes(A[n - 1], primes);
 
        int[] dp = new int[n];
 
        // Initialize last element with 1
        // as that is the intest possible
        dp[n - 1] = 1;
        mpp.put(A[n - 1], n - 1);
 
        // Iterate from the back and find the intest
        for (int i = n - 2; i >= 0; i--)
        {
 
            // Get the number
            int num = A[i];
 
            // Initialize dp[i] as 1
            // as the element will only me in
            // the subsequence .
            dp[i] = 1;
            int maxi = 0;
 
            // Iterate in all the primes and
            // multiply to get the next element
            for (int it : primes)
            {
 
                // Next element if multiplied with it
                int xx = num * it;
 
                // If exceeds the last element
                // then break
                if (xx > A[n - 1])
                    break;
 
                // If the number is there in the array
                else if (mpp.get(xx) != null && mpp.get(xx) != 0)
                {
 
                        // Get the maximum most element
                        dp[i] = Math.max(dp[i], 1 + dp[mpp.get(xx)]);
                }
            }
 
            // Hash the element
            mpp.put(A[i], i);
        }
        int ans = 1;
 
        // Find the intest
        for (int i = 0; i < n; i++)
            ans = Math.max(ans, dp[i]);
 
        return ans;
    }
 
    // Driver code
    public static void main(String[] args)
    {
        int[] a = { 1, 2, 5, 6, 12, 35, 60, 385 };
        int n = a.length;
        System.out.println(findLongest(a, n));
 
    }
}
 
// This code is contributed by
// sanjeev2552


Python3
# Python3 program to implement the
# above approach
 
from math import sqrt
 
# Function to pre-store primes
def SieveOfEratosthenes(MAX, primes) :
 
    prime = [True]*(MAX + 1);
 
    # Sieve method to check if prime or not
    for p in range(2,int(sqrt(MAX)) + 1) :
        if (prime[p] == True) :
            # Multiples
            for i in range(p**2, MAX + 1, p) :
                prime[i] = False;
 
    # Pre-store all the primes
    for i in range(2, MAX + 1) :
        if (prime[i]) :
            primes.append(i);
 
# Function to find the longest subsequence
def findLongest(A, n) :
 
    # Hash map
    mpp = {};
    primes = [];
     
    # Call the function to pre-store the primes
    SieveOfEratosthenes(A[n - 1], primes);
     
    dp = [0] * n ;
     
    # Initialize last element with 1
    # as that is the longest possible
    dp[n - 1] = 1;
    mpp[A[n - 1]] = n - 1;
     
    # Iterate from the back and find the longest
    for i in range(n-2,-1,-1) :
         
        # Get the number
        num = A[i];
         
        # Initialize dp[i] as 1
        # as the element will only me in
        # the subsequence
        dp[i] = 1;
        maxi = 0;
         
        # Iterate in all the primes and
        # multiply to get the next element
        for it in primes :
             
            # Next element if multiplied with it
            xx = num * it;
             
            # If exceeds the last element
            # then break
            if (xx > A[n - 1]) :
                break;
                 
            # If the number is there in the array
            elif xx in mpp :
                # Get the maximum most element
                dp[i] = max(dp[i], 1 + dp[mpp[xx]]);
                 
        # Hash the element
        mpp[A[i]] = i;
         
    ans = 1;
         
    # Find the longest
    for i in range(n) :
        ans = max(ans, dp[i]);
         
    return ans;
 
# Driver Code
if __name__ == "__main__" :
 
    a = [ 1, 2, 5, 6, 12, 35, 60, 385 ];
    n = len(a);
     
    print(findLongest(a, n));
 
# This code is contributed by AnkitRai01


C#
// C# program to implement the
// above approach
using System;
using System.Collections.Generic;
 
class GFG
{
 
    // Function to pre-store primes
    public static void SieveOfEratosthenes(int MAX,
                                      List primes)
    {
        Boolean[] prime = new Boolean[MAX + 1];
        for (int i = 0; i < MAX + 1; i++)
            prime[i] = true;
 
        // Sieve method to check if prime or not
        for (int p = 2; p * p <= MAX; p++)
        {
            if (prime[p] == true)
            {
                // Multiples
                for (int i = p * p; i <= MAX; i += p)
                    prime[i] = false;
            }
        }
 
        // Pre-store all the primes
        for (int i = 2; i <= MAX; i++)
        {
            if (prime[i])
                primes.Add(i);
        }
    }
 
    // Function to find the intest subsequence
    public static int findLongest(int[] A, int n)
    {
 
        // Hash map
        Dictionary mpp = new Dictionary();
        List primes = new List();
 
        // Call the function to pre-store the primes
        SieveOfEratosthenes(A[n - 1], primes);
 
        int[] dp = new int[n];
 
        // Initialize last element with 1
        // as that is the intest possible
        dp[n - 1] = 1;
        mpp.Add(A[n - 1], n - 1);
 
        // Iterate from the back and find the intest
        for (int i = n - 2; i >= 0; i--)
        {
 
            // Get the number
            int num = A[i];
 
            // Initialize dp[i] as 1
            // as the element will only me in
            // the subsequence .
            dp[i] = 1;
 
            // Iterate in all the primes and
            // multiply to get the next element
            foreach (int it in primes)
            {
 
                // Next element if multiplied with it
                int xx = num * it;
 
                // If exceeds the last element
                // then break
                if (xx > A[n - 1])
                    break;
 
                // If the number is there in the array
                else if (mpp.ContainsKey(xx) && mpp[xx] != 0)
                {
 
                    // Get the maximum most element
                    dp[i] = Math.Max(dp[i], 1 + dp[mpp[xx]]);
                }
            }
 
            // Hash the element
            if(mpp.ContainsKey(A[i]))
                mpp[A[i]] = i;
            else
                mpp.Add(A[i], i);
        }
        int ans = 1;
 
        // Find the intest
        for (int i = 0; i < n; i++)
            ans = Math.Max(ans, dp[i]);
 
        return ans;
    }
 
    // Driver code
    public static void Main(String[] args)
    {
        int[] a = { 1, 2, 5, 6, 12, 35, 60, 385 };
        int n = a.Length;
        Console.WriteLine(findLongest(a, n));
    }
}
 
// This code is contributed by Rajput-Ji


Javascript


输出:
5

时间复杂度:O(N log N)
辅助空间:O(N)

如果您希望与专家一起参加现场课程,请参阅DSA 现场工作专业课程学生竞争性编程现场课程