Open In App

Count L-length arrays possible made up of first N natural numbers and each element dividing the next element

Last Updated : 31 Jul, 2023
Comments
Improve
Suggest changes
Like Article
Like
Report

Given two positive integers N and L, the task is to find the number of L-length arrays made up of first N natural numbers such that every element in the array divides its next element.

Examples:

Input: N = 3, L = 3
Output: 7
Explanation:
Following arrays has elements from the range [1, 3] and each array element divides its next element:

  1. {1, 1, 1}
  2. {1, 1, 2}
  3. {1, 2, 2}
  4. {1, 1, 3}
  5. {1, 3, 3}
  6. {2, 2, 2}
  7. {3, 3, 3}

Therefore, the count of arrays is 7.

Input: N = 2, L = 4
Output: 5

Approach: The given problem can be solved by using Dynamic Programming and the idea of Sieve of Eratosthenes. Follow the steps below to solve the problem:

  • Initialize a 2D array dp[][] where dp[i][j] denotes the number of sequences of length i that ends with j and initialize dp[0][1] as 1.
  • Iterate over the range [0, L - 1] using the variable i and nested iterate over the range [1, N] using the variable j:
    • As the next element of the constructed array should be multiple of the current element, therefore iterate over the range [j, N] with an increment of j and update the value of dp[i + 1][k] to the value dp[i][j] + dp[i + 1][k].
  • Initialize a variable, say answer as 0 that stores the resultant number of arrays.
  • Iterate over the range [1, N] and add the value of dp[L][i] to the variable ans.
  • After completing the above steps, print the value of ans as the result.

Below is the implementation of the above approach:

C++
// C++ program for the above approach

#include <bits/stdc++.h>
using namespace std;

// Function to find the number of
// arrays of length L such that each
// element divides the next element
int numberOfArrays(int n, int l)
{

    // Stores the number of sequences
    // of length i that ends with j
    int dp[l + 1][n + 1];

    // Initialize 2D array dp[][] as 0
    memset(dp, 0, sizeof dp);

    // Base Case
    dp[0][1] = 1;

    // Iterate over the range [0, l]
    for (int i = 0; i < l; i++) {
        for (int j = 1; j <= n; j++) {

            // Iterate for all multiples
            // of j
            for (int k = j; k <= n; k += j) {

                // Incrementing dp[i+1][k]
                // by dp[i][j] as the next
                // element is multiple of j
                dp[i + 1][k] += dp[i][j];
            }
        }
    }

    // Stores the number of arrays
    int ans = 0;

    for (int i = 1; i <= n; i++) {

        // Add all array of length
        // L that ends with i
        ans += dp[l][i];
    }

    // Return the resultant count
    return ans;
}

// Driver Code
int main()
{
    int N = 2, L = 4;
    cout << numberOfArrays(N, L);

    return 0;
}
Java
// Java program for the above approach

import java.io.*;

class GFG {
    
    static int numberOfArrays(int n, int l)
    {
        // Stores the number of sequences
    // of length i that ends with j
    int[][] dp=new int[l + 1][n + 1];
 
    
    
 
    // Base Case
    dp[0][1] = 1;
 
    // Iterate over the range [0, l]
    for (int i = 0; i < l; i++) {
        for (int j = 1; j <= n; j++) {
 
            // Iterate for all multiples
            // of j
            for (int k = j; k <= n; k += j) {
 
                // Incrementing dp[i+1][k]
                // by dp[i][j] as the next
                // element is multiple of j
                dp[i + 1][k] += dp[i][j];
            }
        }
    }
 
    // Stores the number of arrays
    int ans = 0;
 
    for (int i = 1; i <= n; i++) {
 
        // Add all array of length
        // L that ends with i
        ans += dp[l][i];
    }
 
    // Return the resultant count
    return ans;
    }
    
    // Driver Code
    public static void main (String[] args) {
        
        int N = 2, L = 4;
        System.out.println(numberOfArrays(N, L));
    }
}

// This code is contributed by unknown2108
Python3
# Python3 program for the above approach

# Function to find the number of
# arrays of length L such that each
# element divides the next element
def numberOfArrays(n, l):
    
    # Stores the number of sequences
    # of length i that ends with j
    dp = [[0 for i in range(n + 1)] 
             for i in range(l + 1)]

    # Initialize 2D array dp[][] as 0a
    # memset(dp, 0, sizeof dp)

    # Base Case
    dp[0][1] = 1

    # Iterate over the range [0, l]
    for i in range(l):
        for j in range(1, n + 1):
            
            # Iterate for all multiples
            # of j
            for k in range(j, n + 1, j):
                
                # Incrementing dp[i+1][k]
                # by dp[i][j] as the next
                # element is multiple of j
                dp[i + 1][k] += dp[i][j]

    # Stores the number of arrays
    ans = 0

    for i in range(1, n + 1):
        
        # Add all array of length
        # L that ends with i
        ans += dp[l][i]

    # Return the resultant count
    return ans

# Driver Code
if __name__ == '__main__':
    
    N, L = 2, 4
    
    print(numberOfArrays(N, L))

# This code is contributed by mohit kumar 29
C#
// C# program for the above approach
using System;
using System.Collections.Generic;

class GFG{

// Function to find the number of
// arrays of length L such that each
// element divides the next element
static int numberOfArrays(int n, int l)
{

    // Stores the number of sequences
    // of length i that ends with j
    int [,]dp = new int[l + 1,n + 1];

    // Initialize 2D array dp[][] as 0
    for(int i = 0; i < l + 1; i++){
      for(int j = 0; j < n + 1; j++)
        dp[i, j] = 0;
    }

    // Base Case
    dp[0, 1] = 1;

    // Iterate over the range [0, l]
    for (int i = 0; i < l; i++) {
        for (int j = 1; j <= n; j++) {

            // Iterate for all multiples
            // of j
            for (int k = j; k <= n; k += j) {

                // Incrementing dp[i+1][k]
                // by dp[i][j] as the next
                // element is multiple of j
                dp[i + 1,k] += dp[i,j];
            }
        }
    }

    // Stores the number of arrays
    int ans = 0;

    for (int i = 1; i <= n; i++) {

        // Add all array of length
        // L that ends with i
        ans += dp[l,i];
    }

    // Return the resultant count
    return ans;
}

// Driver Code
public static void Main()
{
    int N = 2, L = 4;
    Console.Write(numberOfArrays(N, L));
}
}

// This code is contributed by SURENDRA_GANGWAR.
JavaScript
<script>

// JavaScript program for the above approach

// Function to find the number of
// arrays of length L such that each
// element divides the next element
function numberOfArrays(n, l)
{
 
    // Stores the number of sequences
    // of length i that ends with j
   
    let dp= Array(l+1).fill().map(() =>
    Array(n+1).fill(0));
    
    // Initialize 2D array dp[][] as 0
    
 
    // Base Case
    dp[0][1] = 1;
 
    // Iterate over the range [0, l]
    for (let i = 0; i < l; i++) {
        for (let j = 1; j <= n; j++) {
 
            // Iterate for all multiples
            // of j
            for (let k = j; k <= n; k += j) {
 
                // Incrementing dp[i+1][k]
                // by dp[i][j] as the next
                // element is multiple of j
                dp[i + 1][k] += dp[i][j];
            }
        }
    }
 
    // Stores the number of arrays
    let ans = 0;
 
    for (let i = 1; i <= n; i++) {
 
        // Add all array of length
        // L that ends with i
        ans += dp[l][i];
    }
 
    // Return the resultant count
    return ans;
}
 
// Driver Code

    let N = 2, L = 4;
    document.write( numberOfArrays(N, L));
 
// This code is contributed by
// Potta Lokesh
    
</script>

Output
5

Time Complexity: O(N*L*log N)
Auxiliary Space: O(N*L)

Efficient approach : Space optimization

In previous approach the current value dp[i][j] is only depend upon the current and previous row values of DP. So to optimize the space complexity we use a single 1D array to store the computations.

Implementation steps:

  • Create a 1D vector dp of size n+1.
  • Set a base case by initializing the values of DP .
  • Now iterate over subproblems by the help of nested loop and get the current value from previous computations.
  • Now Create a temporary 1d vector temp used to store the current values from previous computations.
  • After every iteration assign the value of temp to dp for further iteration.
  • Initialize a variable ans to store the final answer and update it by iterating through the Dp.
  • At last return and print the final answer stored in ans .

Implementation: 

C++
#include <bits/stdc++.h>
using namespace std;

// Function to find the number of
// arrays of length L such that each
// element divides the next element
int numberOfArrays(int n, int l)
{

    // Stores the number of sequences
    // of length i that ends with j
    vector<int> dp(n + 1);

    // Base Case
    dp[1] = 1;

    // Iterate over the range [0, l]
    for (int i = 0; i < l; i++) {
        vector<int> temp(n + 1);
        for (int j = 1; j <= n; j++) {

            // Iterate for all multiples
            // of j
            for (int k = j; k <= n; k += j) {

                // Incrementing dp[k]
                // by dp[j] as the next
                // element is multiple of j
                temp[k] += dp[j];
            }
        }
        dp = temp;
    }

    // Stores the number of arrays
    int ans = 0;

    for (int i = 1; i <= n; i++) {

        // Add all array of length
        // L that ends with i
        ans += dp[i];
    }

    // Return the resultant count
    return ans;
}

// Driver Code
int main()
{
    int N = 2, L = 4;
    cout << numberOfArrays(N, L);

    return 0;
}
// --- by bhardwajji
Java
import java.util.*;

class Main {

    // Function to find the number of
    // arrays of length L such that each
    // element divides the next element
    public static int numberOfArrays(int n, int l) {

        // Stores the number of sequences
        // of length i that ends with j
        int[] dp = new int[n + 1];

        // Base Case
        dp[1] = 1;

        // Iterate over the range [0, l]
        for (int i = 0; i < l; i++) {
            int[] temp = new int[n + 1];
            for (int j = 1; j <= n; j++) {

                // Iterate for all multiples
                // of j
                for (int k = j; k <= n; k += j) {

                    // Incrementing dp[k]
                    // by dp[j] as the next
                    // element is multiple of j
                    temp[k] += dp[j];
                }
            }
            dp = temp;
        }

        // Stores the number of arrays
        int ans = 0;

        for (int i = 1; i <= n; i++) {

            // Add all array of length
            // L that ends with i
            ans += dp[i];
        }

        // Return the resultant count
        return ans;
    }

    // Driver Code
    public static void main(String[] args) {
        int N = 2, L = 4;
        System.out.println(numberOfArrays(N, L));
    }
}
Python3
def numberOfArrays(n, l):
    # Stores the number of sequences
    # of length i that ends with j
    dp = [0] * (n + 1)
    
    # Base Case
    dp[1] = 1
    
    # Iterate over the range [0, l]
    for i in range(l):
        temp = [0] * (n + 1)
        for j in range(1, n + 1):
            # Iterate for all multiples
            # of j
            for k in range(j, n + 1, j):
                # Incrementing dp[k]
                # by dp[j] as the next
                # element is a multiple of j
                temp[k] += dp[j]
        dp = temp
    
    # Stores the number of arrays
    ans = 0
    
    for i in range(1, n + 1):
        # Add all arrays of length
        # L that end with i
        ans += dp[i]
    
    # Return the resultant count
    return ans

# Driver Code
N = 2
L = 4
print(numberOfArrays(N, L))
C#
using System;

public class GFG {
    // Function to find the number of
    // arrays of length L such that each
    // element divides the next element
    public static int NumberOfArrays(int n, int l)
    {
        // Stores the number of sequences
        // of length i that ends with j
        int[] dp = new int[n + 1];

        // Base Case
        dp[1] = 1;

        // Iterate over the range [0, l]
        for (int i = 0; i < l; i++)
        {
            int[] temp = new int[n + 1];
            for (int j = 1; j <= n; j++)
            {
                // Iterate for all multiples
                // of j
                for (int k = j; k <= n; k += j)
                {
                    // Incrementing dp[k]
                    // by dp[j] as the next
                    // element is multiple of j
                    temp[k] += dp[j];
                }
            }
            dp = temp;
        }

        // Stores the number of arrays
        int ans = 0;

        for (int i = 1; i <= n; i++)
        {
            // Add all array of length
            // L that ends with i
            ans += dp[i];
        }

        // Return the resultant count
        return ans;
    }

    // Driver Code
    public static void Main(string[] args)
    {
        int N = 2, L = 4;
        Console.WriteLine(NumberOfArrays(N, L));
    }
}
JavaScript
// Function to find the number of
// arrays of length L such that each
// element divides the next element
function numberOfArrays(n, l) {
    // Stores the number of sequences
    // of length i that ends with j
    let dp = new Array(n + 1).fill(0);

    // Base Case
    dp[1] = 1;

    // Iterate over the range [0, l]
    for (let i = 0; i < l; i++) {
        let temp = new Array(n + 1).fill(0);
        for (let j = 1; j <= n; j++) {

            // Iterate for all multiples
            // of j
            for (let k = j; k <= n; k += j) {

                // Incrementing dp[k]
                // by dp[j] as the next
                // element is multiple of j
                temp[k] += dp[j];
            }
        }
        dp = temp;
    }

    // Stores the number of arrays
    let ans = 0;

    for (let i = 1; i <= n; i++) {

        // Add all arrays of length
        // L that ends with i
        ans += dp[i];
    }

    // Return the resultant count
    return ans;
}

// Driver Code
const N = 2,
    L = 4;
console.log(numberOfArrays(N, L));
// sinudp5vi

Output
5

Time Complexity: O(n^2 * L)
Auxiliary Space: O(N)


Next Article

Similar Reads