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:
#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 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 |
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);
}
} |
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. |
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()
|
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)