Open In App

Largest subsequence such that all indices and all values are multiples individually

Given an array arr[] of N positive integers, the task is to find the largest strictly increasing subsequence of arr[] such that the indices of the selected elements in arr[], and the selected elements are multiples of each other individually. 
Note: Consider 1 based indexing for the array arr[].
Examples: 
 

Input: arr[] = {1, 4, 2, 3, 6, 4, 9} 
Output:
Explanation: 
We can choose index 1, 3, 6 and values are 1, 2, 4: 
Here every greater index is divisible by smaller index and every greater index value is greater than the smaller index value. 
Input: arr[] = {5, 3, 4, 6} 
Output:
Explanation: 
We can choose index 1 and 3 and values are 3 and 6: 
Here, every greater index is divisible by smaller index and every greater index value is greater than the smaller index value. 
 



 

Naive Approach: 
The naive approach is to simply generate all possible subsequence and for each subsequence check two conditions: 



Out of all possible subsequence which satisfies the given two conditions select the largest subsequence. 
Time Complexity: O( N * 2N
Auxiliary Space: O( N )
Efficient Approach: 
We can optimize the code by using Dynamic Programming by avoiding redundant calculation of the repeated sub problem by caching its result.

  1. Create an array dp[] of size equal to the size of arr[], where dp[i] represents size of largest subsequence till i-th index which satisfies the given conditions. 
     
  2. Initialize array dp[] with 0. 
     
  3. Now, iterate the array arr[] from the end.
  4. For each index find the indices j which divide the current index and check if the value at current index is greater than the element at index j.
  5. If it is then update dp[j] as: 
     

dp[j] = max(dp[current] + 1, dp[j]) 
 

Finally, traverse the array dp[] and print the maximum value.
Below is the implementation of the efficient approach:




// C++ program for the above approach
#include <bits/stdc++.h>
using namespace std;
 
// Function that print maximum length
// of array
void maxLength(int arr[], int n)
{
    // dp[] array to store the
    // maximum length
    vector<int> dp(n, 1);
 
    for (int i = n - 1; i > 1; i--) {
 
        // Find all divisors of i
        for (int j = 1;
             j <= sqrt(i); j++) {
 
            if (i % j == 0) {
                int s = i / j;
 
                if (s == j) {
 
                    // If the current value
                    // is greater than the
                    // divisor's value
                    if (arr[i] > arr[s]) {
 
                        dp[s] = max(dp[i] + 1,
                                    dp[s]);
                    }
                }
                else {
 
                    // If current value
                    // is greater
                    // than the divisor's value
                    // and s is not equal
                    // to current index
                    if (s != i
                        && arr[i] > arr[s])
                        dp[s] = max(dp[i] + 1,
                                    dp[s]);
 
                    // Condition if current
                    // value is greater
                    // than the divisor's value
                    if (arr[i] > arr[j]) {
                        dp[j] = max(dp[i] + 1,
                                    dp[j]);
                    }
                }
            }
        }
    }
 
    int max = 0;
 
    // Computing the greatest value
    for (int i = 1; i < n; i++) {
        if (dp[i] > max)
            max = dp[i];
    }
 
    // Printing maximum length of array
    cout << max << "\n";
}
 
// Driver Code
int main()
{
    // Given array arr[]
    int arr[] = { 0, 1, 4, 2, 3, 6, 4, 9 };
    int size = sizeof(arr) / sizeof(arr[0]);
 
    // Function Call
    maxLength(arr, size);
    return 0;
}




// Java program for the above approach
import java.util.*;
import java.io.*;
 
class GFG{
     
// Function that print maximum length
// of array
static void maxLength(int arr[], int n)
{
     
    // dp[] array to store the
    // maximum length
    int dp[] = new int[n];
    for(int i = 1; i < n; i++)
    {
        dp[i] = 1;
    }
 
    for(int i = n - 1; i > 1; i--)
    {
         
        // Find all divisors of i
        for(int j = 1;
                j <= Math.sqrt(i); j++)
        {
            if (i % j == 0)
            {
                int s = i / j;
 
                if (s == j)
                {
                     
                    // If the current value
                    // is greater than the
                    // divisor's value
                    if (arr[i] > arr[s])
                    {
                        dp[s] = Math.max(dp[i] + 1,
                                         dp[s]);
                    }
                }
                else
                {
                     
                    // If current value is greater
                    // than the divisor's value
                    // and s is not equal
                    // to current index
                    if (s != i && arr[i] > arr[s])
                        dp[s] = Math.max(dp[i] + 1,
                                         dp[s]);
     
                    // Condition if current
                    // value is greater
                    // than the divisor's value
                    if (arr[i] > arr[j])
                    {
                        dp[j] = Math.max(dp[i] + 1,
                                         dp[j]);
                    }
                }
            }
        }
    }
    int max = 0;
 
    // Computing the greatest value
    for(int i = 1; i < n; i++)
    {
        if (dp[i] > max)
            max = dp[i];
    }
     
    // Printing maximum length of array
    System.out.println(max);
}
 
// Driver Code
public static void main(String[] args)
{
     
    // Given array arr[]
    int arr[] = { 0, 1, 4, 2, 3, 6, 4, 9 };
    int size = arr.length;
 
    // Function call
    maxLength(arr, size);
}
}
 
// This code is contributed by sanjoy_62




# Python3 program for the above approach
from math import *
 
# Function that print maximum length
# of array
def maxLength (arr, n):
 
    # dp[] array to store the
    # maximum length
    dp = [1] * n
 
    for i in range(n - 1, 1, -1):
 
        # Find all divisors of i
        for j in range(1, int(sqrt(i)) + 1):
            if (i % j == 0):
                s = i // j
 
                if (s == j):
 
                    # If the current value
                    # is greater than the
                    # divisor's value
                    if (arr[i] > arr[s]):
                        dp[s] = max(dp[i] + 1, dp[s])
 
                else:
                    # If current value
                    # is greater
                    # than the divisor's value
                    # and s is not equal
                    # to current index
                    if (s != i and arr[i] > arr[s]):
                        dp[s] = max(dp[i] + 1, dp[s])
 
                    # Condition if current
                    # value is greater
                    # than the divisor's value
                    if (arr[i] > arr[j]):
                        dp[j] = max(dp[i] + 1, dp[j])
 
    Max = 0
 
    # Computing the greatest value
    for i in range(1, n):
        if (dp[i] > Max):
            Max = dp[i]
 
    # Printing maximum length of array
    print(Max)
 
# Driver Code
if __name__ == '__main__':
 
    # Given array arr[]
    arr = [ 0, 1, 4, 2, 3, 6, 4, 9]
    size = len(arr)
 
    # Function call
    maxLength(arr, size)
 
# This code is contributed by himanshu77




// C# program for the above approach
using System;
 
class GFG{
 
// Function that print maximum length
// of array
static void maxLength(int[] arr, int n)
{
     
    // dp[] array to store the
    // maximum length
    int[] dp = new int[n];
    for(int i = 1; i < n; i++)
    {
        dp[i] = 1;
    }
 
    for(int i = n - 1; i > 1; i--)
    {
         
        // Find all divisors of i
        for(int j = 1;
                j <= Math.Sqrt(i); j++)
        {
            if (i % j == 0)
            {
                int s = i / j;
                 
                if (s == j)
                {
                     
                    // If the current value
                    // is greater than the
                    // divisor's value
                    if (arr[i] > arr[s])
                    {
                        dp[s] = Math.Max(dp[i] + 1,
                                         dp[s]);
                    }
                }
                else
                {
                     
                    // If current value is greater
                    // than the divisor's value
                    // and s is not equal
                    // to current index
                    if (s != i && arr[i] > arr[s])
                        dp[s] = Math.Max(dp[i] + 1,
                                         dp[s]);
     
                    // Condition if current
                    // value is greater
                    // than the divisor's value
                    if (arr[i] > arr[j])
                    {
                        dp[j] = Math.Max(dp[i] + 1,
                                         dp[j]);
                    }
                }
            }
        }
    }
    int max = 0;
 
    // Computing the greatest value
    for(int i = 1; i < n; i++)
    {
        if (dp[i] > max)
            max = dp[i];
    }
 
    // Printing maximum length of array
    Console.WriteLine(max);
}
 
// Driver Code
public static void Main()
{
     
    // Given array arr[]
    int[] arr = new int[] { 0, 1, 4, 2,
                            3, 6, 4, 9 };
    int size = arr.Length;
 
    // Function call
    maxLength(arr, size);
}
}
 
// This code is contributed by sanjoy_62




<script>
 
// Javascript Program to implement
// the above approach
 
// Function that print maximum length
// of array
function maxLength(arr, n)
{
       
    // dp[] array to store the
    // maximum length
    let dp = [];
    for(let i = 1; i < n; i++)
    {
        dp[i] = 1;
    }
   
    for(let i = n - 1; i > 1; i--)
    {
           
        // Find all divisors of i
        for(let j = 1;
                j <= Math.sqrt(i); j++)
        {
            if (i % j == 0)
            {
                let s = i / j;
                if (s == j)
                {
                       
                    // If the current value
                    // is greater than the
                    // divisor's value
                    if (arr[i] > arr[s])
                    {
                        dp[s] = Math.max(dp[i] + 1,
                                         dp[s]);
                    }
                }
                else
                {
                       
                    // If current value is greater
                    // than the divisor's value
                    // and s is not equal
                    // to current index
                    if (s != i && arr[i] > arr[s])
                        dp[s] = Math.max(dp[i] + 1,
                                         dp[s]);
       
                    // Condition if current
                    // value is greater
                    // than the divisor's value
                    if (arr[i] > arr[j])
                    {
                        dp[j] = Math.max(dp[i] + 1,
                                         dp[j]);
                    }
                }
            }
        }
    }
    let max = 0;
   
    // Computing the greatest value
    for(let i = 1; i < n; i++)
    {
        if (dp[i] > max)
            max = dp[i];
    }
       
    // Printing maximum length of array
    document.write(max);
}
 
// Driver Code
 
    // Given array arr[]
    let arr = [ 0, 1, 4, 2, 3, 6, 4, 9 ];
    let size = arr.length;
   
    // Function call
    maxLength(arr, size);
     
    // This code is contributed by chinmoy1997pal.
</script>

Output: 
3

 

Time Complexity: O(N*(sqrt(N)) Since, for each index of the array, we calculate its all divisor, this takes O(sqrt(N)) 
Auxiliary Space: O(N)
 


Article Tags :