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, 1, 2}
- {1, 2, 2}
- {1, 1, 3}
- {1, 3, 3}
- {2, 2, 2}
- {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++
#include <bits/stdc++.h>
using namespace std;
int numberOfArrays( int n, int l)
{
int dp[l + 1][n + 1];
memset (dp, 0, sizeof dp);
dp[0][1] = 1;
for ( int i = 0; i < l; i++) {
for ( int j = 1; j <= n; j++) {
for ( int k = j; k <= n; k += j) {
dp[i + 1][k] += dp[i][j];
}
}
}
int ans = 0;
for ( int i = 1; i <= n; i++) {
ans += dp[l][i];
}
return ans;
}
int main()
{
int N = 2, L = 4;
cout << numberOfArrays(N, L);
return 0;
}
|
Java
import java.io.*;
class GFG {
static int numberOfArrays( int n, int l)
{
int [][] dp= new int [l + 1 ][n + 1 ];
dp[ 0 ][ 1 ] = 1 ;
for ( int i = 0 ; i < l; i++) {
for ( int j = 1 ; j <= n; j++) {
for ( int k = j; k <= n; k += j) {
dp[i + 1 ][k] += dp[i][j];
}
}
}
int ans = 0 ;
for ( int i = 1 ; i <= n; i++) {
ans += dp[l][i];
}
return ans;
}
public static void main (String[] args) {
int N = 2 , L = 4 ;
System.out.println(numberOfArrays(N, L));
}
}
|
Python3
def numberOfArrays(n, l):
dp = [[ 0 for i in range (n + 1 )]
for i in range (l + 1 )]
dp[ 0 ][ 1 ] = 1
for i in range (l):
for j in range ( 1 , n + 1 ):
for k in range (j, n + 1 , j):
dp[i + 1 ][k] + = dp[i][j]
ans = 0
for i in range ( 1 , n + 1 ):
ans + = dp[l][i]
return ans
if __name__ = = '__main__' :
N, L = 2 , 4
print (numberOfArrays(N, L))
|
C#
using System;
using System.Collections.Generic;
class GFG{
static int numberOfArrays( int n, int l)
{
int [,]dp = new int [l + 1,n + 1];
for ( int i = 0; i < l + 1; i++){
for ( int j = 0; j < n + 1; j++)
dp[i, j] = 0;
}
dp[0, 1] = 1;
for ( int i = 0; i < l; i++) {
for ( int j = 1; j <= n; j++) {
for ( int k = j; k <= n; k += j) {
dp[i + 1,k] += dp[i,j];
}
}
}
int ans = 0;
for ( int i = 1; i <= n; i++) {
ans += dp[l,i];
}
return ans;
}
public static void Main()
{
int N = 2, L = 4;
Console.Write(numberOfArrays(N, L));
}
}
|
Javascript
<script>
function numberOfArrays(n, l)
{
let dp= Array(l+1).fill().map(() =>
Array(n+1).fill(0));
dp[0][1] = 1;
for (let i = 0; i < l; i++) {
for (let j = 1; j <= n; j++) {
for (let k = j; k <= n; k += j) {
dp[i + 1][k] += dp[i][j];
}
}
}
let ans = 0;
for (let i = 1; i <= n; i++) {
ans += dp[l][i];
}
return ans;
}
let N = 2, L = 4;
document.write( numberOfArrays(N, L));
</script>
|
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;
int numberOfArrays( int n, int l)
{
vector< int > dp(n + 1);
dp[1] = 1;
for ( int i = 0; i < l; i++) {
vector< int > temp(n + 1);
for ( int j = 1; j <= n; j++) {
for ( int k = j; k <= n; k += j) {
temp[k] += dp[j];
}
}
dp = temp;
}
int ans = 0;
for ( int i = 1; i <= n; i++) {
ans += dp[i];
}
return ans;
}
int main()
{
int N = 2, L = 4;
cout << numberOfArrays(N, L);
return 0;
}
|
Java
import java.util.*;
class Main {
public static int numberOfArrays( int n, int l) {
int [] dp = new int [n + 1 ];
dp[ 1 ] = 1 ;
for ( int i = 0 ; i < l; i++) {
int [] temp = new int [n + 1 ];
for ( int j = 1 ; j <= n; j++) {
for ( int k = j; k <= n; k += j) {
temp[k] += dp[j];
}
}
dp = temp;
}
int ans = 0 ;
for ( int i = 1 ; i <= n; i++) {
ans += dp[i];
}
return ans;
}
public static void main(String[] args) {
int N = 2 , L = 4 ;
System.out.println(numberOfArrays(N, L));
}
}
|
Python3
def numberOfArrays(n, l):
dp = [ 0 ] * (n + 1 )
dp[ 1 ] = 1
for i in range (l):
temp = [ 0 ] * (n + 1 )
for j in range ( 1 , n + 1 ):
for k in range (j, n + 1 , j):
temp[k] + = dp[j]
dp = temp
ans = 0
for i in range ( 1 , n + 1 ):
ans + = dp[i]
return ans
N = 2
L = 4
print (numberOfArrays(N, L))
|
C#
using System;
public class GFG {
public static int NumberOfArrays( int n, int l)
{
int [] dp = new int [n + 1];
dp[1] = 1;
for ( int i = 0; i < l; i++)
{
int [] temp = new int [n + 1];
for ( int j = 1; j <= n; j++)
{
for ( int k = j; k <= n; k += j)
{
temp[k] += dp[j];
}
}
dp = temp;
}
int ans = 0;
for ( int i = 1; i <= n; i++)
{
ans += dp[i];
}
return ans;
}
public static void Main( string [] args)
{
int N = 2, L = 4;
Console.WriteLine(NumberOfArrays(N, L));
}
}
|
Javascript
function numberOfArrays(n, l) {
let dp = new Array(n + 1).fill(0);
dp[1] = 1;
for (let i = 0; i < l; i++) {
let temp = new Array(n + 1).fill(0);
for (let j = 1; j <= n; j++) {
for (let k = j; k <= n; k += j) {
temp[k] += dp[j];
}
}
dp = temp;
}
let ans = 0;
for (let i = 1; i <= n; i++) {
ans += dp[i];
}
return ans;
}
const N = 2,
L = 4;
console.log(numberOfArrays(N, L));
|
Time Complexity: O(n^2 * L)
Auxiliary Space: O(N)