Open In App

Longest strictly decreasing subsequence such that no two adjacent elements are coprime

Last Updated : 07 Mar, 2024
Improve
Improve
Like Article
Like
Save
Share
Report

Given an array arr[], find the length of the longest strictly decreasing subsequence such that no two adjacent elements are coprime.

Examples:

Input: N = 5, arr[]= {9, 6, 4, 3, 2}
Output: 4
Explanation: The longest strictly decreasing non-coprime subsequence is {9, 6, 4, 2} having length = 4.

Input: N=4, arr[]={6, 4, 2, 1}
Output: 3
Explanation: The longest strictly decreasing non-coprime subsequence is {6, 4, 2} having length = 3.

Approach: To solve the problem, follow the below idea:

The approach is to use Dynamic Programming to find the length of the longest decreasing non-coprime subsequence for a given array of integers. The approach involves iterating through each element of the array and, for each element, considering its divisors to update a dynamic programming table (dp) that keeps track of the longest decreasing non-coprime subsequence ending at each divisor.

Step-by-step algorithm:

  • Iterate through each element of the array in reverse order.
  • For each element a[i], find its divisors and update the local subsequence (lcs) by checking the dynamic programming table (dp) for each divisor.
  • Update the longest subsequence (lgs) by taking the maximum of the current lcs + 1 and the existing lgs.
  • Update the dynamic programming table (dp) for each divisor by storing the maximum of the current value and lcs + 1.

Below is the implementation of the above approach:

C++




#include <algorithm>
#include <iostream>
 
using namespace std;
 
const int MAX_N = 100001;
// Array to store the input sequence
int arr[MAX_N];
 
// Dynamic programming table to store the length of the
// longest good subsequence ending at each divisor
int dp[MAX_N];
 
// Function to find the length of the Longest Good
// Subsequence
int getSubsequence(int n)
{
    // Variable to store the length of the longest decreasing
    // subsequence with no adjacent coprime elements
    int lgs = 0;
 
    // Iterate through each element of the array
    for (int i = n ; i > 0; i--) {
        int x = arr[i];
        // Variable to store the local subsequence for
        // the current element
        int lcs = 0;
 
        // Iterate through divisors of the current element
        for (int j = 1; j * j <= x; j++) {
            if (x % j == 0) {
                // Check dynamic programming table for each
                // divisor and update local subsequence
                if (j > 1) {
                    lcs = max(lcs, dp[j]);
                }
                lcs = max(lcs, dp[x / j]);
            }
        }
 
        // Update the length of the longest subsequence
        lgs = max(lgs, lcs + 1);
 
        // Update dynamic programming table for each divisor
        for (int j = 1; j * j <= x; j++) {
            if (x % j == 0) {
                dp[j] = max(dp[j], lcs + 1);
                dp[x / j] = max(dp[x / j], lcs + 1);
            }
        }
    }
 
    return lgs;
}
 
int main()
{
    int n = 4;
    int input[] = { 6, 4, 2, 1 };
     
    for(int i = 0; i < 4; i++) {
        arr[i + 1] = input[i];
    }
    // Call the function to find the length of the longest
    // good subsequence
    int result = getSubsequence(n);
 
    // Print the result
    cout << result;
 
    return 0;
}


Java




// Java Implementation
 
import java.util.Arrays;
 
public class Main {
    static final int MAX_N = 100001;
    // Array to store the input sequence
    static int[] arr = new int[MAX_N];
 
    // Dynamic programming table to store the length of the
    // longest good subsequence ending at each divisor
    static int[] dp = new int[MAX_N];
 
    // Function to find the length of the Longest Good
    // Subsequence
    static int getSubsequence(int n) {
        // Variable to store the length of the longest decreasing
        // subsequence with no adjacent coprime elements
        int lgs = 0;
 
        // Iterate through each element of the array
        for (int i = n; i > 0; i--) {
            int x = arr[i];
            // Variable to store the local subsequence for
            // the current element
            int lcs = 0;
 
            // Iterate through divisors of the current element
            for (int j = 1; j * j <= x; j++) {
                if (x % j == 0) {
                    // Check dynamic programming table for each
                    // divisor and update local subsequence
                    if (j > 1) {
                        lcs = Math.max(lcs, dp[j]);
                    }
                    lcs = Math.max(lcs, dp[x / j]);
                }
            }
 
            // Update the length of the longest subsequence
            lgs = Math.max(lgs, lcs + 1);
 
            // Update dynamic programming table for each divisor
            for (int j = 1; j * j <= x; j++) {
                if (x % j == 0) {
                    dp[j] = Math.max(dp[j], lcs + 1);
                    dp[x / j] = Math.max(dp[x / j], lcs + 1);
                }
            }
        }
 
        return lgs;
    }
 
    public static void main(String[] args) {
        int n = 4;
        int[] input = {6, 4, 2, 1};
 
        for (int i = 0; i < 4; i++) {
            arr[i + 1] = input[i];
        }
 
        // Call the function to find the length of the longest
        // good subsequence
        int result = getSubsequence(n);
 
        // Print the result
        System.out.println(result);
    }
}
 
 
// This code is contributed by Sakshi


C#




using System;
 
class Program
{
    const int MAX_N = 100001;
    // Array to store the input sequence
    static int[] arr = new int[MAX_N];
 
    // Dynamic programming table to store the length of the
    // longest good subsequence ending at each divisor
    static int[] dp = new int[MAX_N];
 
    // Function to find the length of the Longest Good
    // Subsequence
    static int GetSubsequence(int n)
    {
        // Variable to store the length of the longest decreasing
        // subsequence with no adjacent coprime elements
        int lgs = 0;
 
        // Iterate through each element of the array
        for (int i = n; i > 0; i--)
        {
            int x = arr[i];
            // Variable to store the local subsequence for
            // the current element
            int lcs = 0;
 
            // Iterate through divisors of the current element
            for (int j = 1; j * j <= x; j++)
            {
                if (x % j == 0)
                {
                    // Check dynamic programming table for each
                    // divisor and update local subsequence
                    if (j > 1)
                    {
                        lcs = Math.Max(lcs, dp[j]);
                    }
                    lcs = Math.Max(lcs, dp[x / j]);
                }
            }
 
            // Update the length of the longest subsequence
            lgs = Math.Max(lgs, lcs + 1);
 
            // Update dynamic programming table for each divisor
            for (int j = 1; j * j <= x; j++)
            {
                if (x % j == 0)
                {
                    dp[j] = Math.Max(dp[j], lcs + 1);
                    dp[x / j] = Math.Max(dp[x / j], lcs + 1);
                }
            }
        }
 
        return lgs;
    }
 
    static void Main()
    {
        int n = 4;
        int[] input = { 6, 4, 2, 1 };
 
        for (int i = 0; i < 4; i++)
        {
            arr[i + 1] = input[i];
        }
 
        // Call the function to find the length of the longest
        // good subsequence
        int result = GetSubsequence(n);
 
        // Print the result
        Console.WriteLine(result);
    }
}


Javascript




const MAX_N = 100001;
// Array to store the input sequence
let arr = new Array(MAX_N).fill(0);
 
// Dynamic programming table to store the length of the
// longest good subsequence ending at each divisor
let dp = new Array(MAX_N).fill(0);
 
// Function to find the length of the Longest Good
// Subsequence
function getSubsequence(n) {
    // Variable to store the length of the longest decreasing
    // subsequence with no adjacent coprime elements
    let lgs = 0;
 
    // Iterate through each element of the array
    for (let i = n; i > 0; i--) {
        let x = arr[i];
        // Variable to store the local subsequence for
        // the current element
        let lcs = 0;
 
        // Iterate through divisors of the current element
        for (let j = 1; j * j <= x; j++) {
            if (x % j == 0) {
                // Check dynamic programming table for each
                // divisor and update local subsequence
                if (j > 1) {
                    lcs = Math.max(lcs, dp[j]);
                }
                lcs = Math.max(lcs, dp[x / j]);
            }
        }
 
        // Update the length of the longest subsequence
        lgs = Math.max(lgs, lcs + 1);
 
        // Update dynamic programming table for each divisor
        for (let j = 1; j * j <= x; j++) {
            if (x % j == 0) {
                dp[j] = Math.max(dp[j], lcs + 1);
                dp[x / j] = Math.max(dp[x / j], lcs + 1);
            }
        }
    }
 
    return lgs;
}
 
function main() {
    let n = 4;
    let input = [6, 4, 2, 1];
 
    for (let i = 0; i < 4; i++) {
        arr[i + 1] = input[i];
    }
 
    // Call the function to find the length of the longest
    // good subsequence
    let result = getSubsequence(n);
 
    // Print the result
    console.log(result);
}
 
// Call the main function
main();
//This code is contributed by Monu.


Python3




import math
 
MAX_N = 100001
# Array to store the input sequence
arr = [0] * MAX_N
 
# Dynamic programming table to store the length of the
# longest good subsequence ending at each divisor
dp = [0] * MAX_N
 
# Function to find the length of the Longest Good
# Subsequence
def getSubsequence(n):
    # Variable to store the length of the longest decreasing
    # subsequence with no adjacent coprime elements
    lgs = 0
 
    # Iterate through each element of the array
    for i in range(n, 0, -1):
        x = arr[i]
        # Variable to store the local subsequence for
        # the current element
        lcs = 0
 
        # Iterate through divisors of the current element
        for j in range(1, int(math.sqrt(x)) + 1):
            if x % j == 0:
                # Check dynamic programming table for each
                # divisor and update local subsequence
                if j > 1:
                    lcs = max(lcs, dp[j])
                lcs = max(lcs, dp[x // j])
 
        # Update the length of the longest subsequence
        lgs = max(lgs, lcs + 1)
 
        # Update dynamic programming table for each divisor
        for j in range(1, int(math.sqrt(x)) + 1):
            if x % j == 0:
                dp[j] = max(dp[j], lcs + 1)
                dp[x // j] = max(dp[x // j], lcs + 1)
 
    return lgs
 
def main():
    n = 4
    input_sequence = [6, 4, 2, 1]
 
    for i in range(4):
        arr[i + 1] = input_sequence[i]
 
    # Call the function to find the length of the longest
    # good subsequence
    result = getSubsequence(n)
 
    print(result)
 
if __name__ == "__main__":
    main()


Output

3

Time Complexity: O(N * sqrt(max_element)), where N is the number of elements in the array and max_element is the maximum element of the array.
Auxiliary Space: O(max_element)



Like Article
Suggest improvement
Share your thoughts in the comments

Similar Reads