Count of sequence of length K in range [1, N] where every element is a multiple of its previous one
Last Updated :
18 Jul, 2023
Given two integers N and K, the task is to find the count of sequences of K elements from the range [1, N] where every element is a multiple of the previous element.
Example:
Input: N = 4, K = 3
Output: 13
Explanation: The sequences that can be made from the integers 1, 2, 3, 4 having 3 elements are: {1, 1, 1}, {2, 2, 2}, {3, 3, 3}, {4, 4, 4}, {1, 1, 2}, {1, 2, 2}, {1, 2, 4}, {1, 1, 3}, {1, 3, 3}, {1, 1, 4}, {1, 4, 4}, {2, 2, 4}, and {2, 4, 4}.
Input: N = 9, K = 5
Output: 111
Approach: The given problem can be solved using recursion with memoization. Follow the below steps to solve the problem:
- Create a 2D array dp[][] which stores the memorized states where dp[i][j] represents the count of sequences of length i having j as their first element.
- Create a recursive function countSequenceUtil(), that takes the length of the sequence and the starting element as arguments, sets the next element as a multiple of the current element, and recursively calls for the remaining sequence.
- Store the answer for the calculated states in the dp[][] array and if for some state the value is already calculated, return it.
- Create a function countSequence() which iterates through all the possible starting elements of the sequence and calls the recursive function to calculate the sequences of K elements with that starting element.
- Maintain the sum of the calculated count for each starting element in a variable ans which is the required value.
Below is the implementation of the above approach:
C++
#include <bits/stdc++.h>
using namespace std;
int static dp[1001][1001];
int countSequenceUtil( int k, int m, int n)
{
if (k == 1) {
return 1;
}
if (dp[k][m] != -1) {
return dp[k][m];
}
int res = 0;
for ( int i = 1; i <= (n / m); i++) {
res += countSequenceUtil(k - 1,
m * i, n);
}
return dp[k][m] = res;
}
int countSequence( int N, int K)
{
memset (dp, -1, sizeof (dp));
int ans = 0;
for ( int i = 1; i <= N; i++) {
ans += countSequenceUtil(K, i, N);
}
return ans;
}
int main()
{
int N = 9;
int K = 5;
cout << countSequence(N, K);
return 0;
}
|
Java
import java.io.*;
class GFG {
static int dp[][] = new int [ 1001 ][ 1001 ];
static int countSequenceUtil( int k, int m, int n)
{
if (k == 1 ) {
return 1 ;
}
if (dp[k][m] != - 1 ) {
return dp[k][m];
}
int res = 0 ;
for ( int i = 1 ; i <= (n / m); i++) {
res += countSequenceUtil(k - 1 ,
m * i, n);
}
return dp[k][m] = res;
}
static int countSequence( int N, int K)
{
for ( int i= 0 ;i<dp.length;i++)
{
for ( int j= 0 ;j<dp[i].length;j++)
{
dp[i][j]=- 1 ;
}
}
int ans = 0 ;
for ( int i = 1 ; i <= N; i++) {
ans += countSequenceUtil(K, i, N);
}
return ans;
}
public static void main (String[] args) {
int N = 9 ;
int K = 5 ;
System.out.println(countSequence(N, K));
}
}
|
Python3
dp = [[ - 1 for i in range ( 1001 )] for j in range ( 1001 )]
def countSequenceUtil(k, m, n):
if (k = = 1 ):
return 1
if (dp[k][m] ! = - 1 ):
return dp[k][m]
res = 0
for i in range ( 1 , (n / / m) + 1 ):
res + = countSequenceUtil(k - 1 ,
m * i, n)
dp[k][m] = res
return dp[k][m]
def countSequence(N, K):
ans = 0
for i in range ( 1 , N + 1 ):
ans + = countSequenceUtil(K, i, N)
return ans
N = 9
K = 5
print (countSequence(N, K))
|
C#
using System;
class GFG {
static int [, ] dp = new int [1001, 1001];
static int countSequenceUtil( int k, int m, int n)
{
if (k == 1) {
return 1;
}
if (dp[k, m] != -1) {
return dp[k, m];
}
int res = 0;
for ( int i = 1; i <= (n / m); i++) {
res += countSequenceUtil(k - 1, m * i, n);
}
return dp[k, m] = res;
}
static int countSequence( int N, int K)
{
for ( int i = 0; i < dp.GetLength(0); i++) {
for ( int j = 0; j < dp.GetLength(1); j++) {
dp[i, j] = -1;
}
}
int ans = 0;
for ( int i = 1; i <= N; i++) {
ans += countSequenceUtil(K, i, N);
}
return ans;
}
public static void Main( string [] args)
{
int N = 9;
int K = 5;
Console.WriteLine(countSequence(N, K));
}
}
|
Javascript
<script>
let dp = new Array(1001).fill(-1).map(() => new Array(1001).fill(-1));
const countSequenceUtil = (k, m, n) => {
if (k == 1) {
return 1;
}
if (dp[k][m] != -1) {
return dp[k][m];
}
let res = 0;
for (let i = 1; i <= parseInt(n / m); i++) {
res += countSequenceUtil(k - 1,
m * i, n);
}
return dp[k][m] = res;
}
const countSequence = (N, K) => {
let ans = 0;
for (let i = 1; i <= N; i++) {
ans += countSequenceUtil(K, i, N);
}
return ans;
}
let N = 9;
let K = 5;
document.write(countSequence(N, K));
</script>
|
Time Complexity: O(N*K*log N)
Auxiliary Space: O(N*K)
Efficient approach : Using DP Tabulation method ( Iterative approach )
The approach to solve this problem is same but DP tabulation(bottom-up) method is better then Dp + memoization(top-down) because memoization method needs extra stack space of recursion calls.
Steps to solve this problem :
- Create a table to store the solution of the subproblems.
- Initialize the table with base cases
- Fill up the table iteratively
- Return the final solution
Implementation :
C++
#include <bits/stdc++.h>
using namespace std;
int countSequence( int N, int K)
{
int dp[K + 1][N + 1];
for ( int i = 1; i <= N; i++) {
dp[1][i] = 1;
}
for ( int k = 2; k <= K; k++) {
for ( int m = 1; m <= N; m++) {
dp[k][m] = 0;
for ( int i = 1; i <= (N / m); i++) {
dp[k][m] += dp[k - 1][m * i];
}
}
}
int ans = 0;
for ( int i = 1; i <= N; i++) {
ans += dp[K][i];
}
return ans;
}
int main()
{
int N = 9;
int K = 5;
cout << countSequence(N, K);
return 0;
}
|
Java
import java.util.*;
public class Main {
static int countSequence( int N, int K)
{
int [][] dp = new int [K + 1 ][N + 1 ];
for ( int i = 1 ; i <= N; i++) {
dp[ 1 ][i] = 1 ;
}
for ( int k = 2 ; k <= K; k++) {
for ( int m = 1 ; m <= N; m++) {
dp[k][m] = 0 ;
for ( int i = 1 ; i <= (N / m); i++) {
dp[k][m] += dp[k - 1 ][m * i];
}
}
}
int ans = 0 ;
for ( int i = 1 ; i <= N; i++) {
ans += dp[K][i];
}
return ans;
}
public static void main(String[] args)
{
int N = 9 ;
int K = 5 ;
System.out.println(countSequence(N, K));
}
}
|
Python3
def countSequence(N, K):
dp = [[ 0 for i in range (N + 1 )] for j in range (K + 1 )]
for i in range ( 1 , N + 1 ):
dp[ 1 ][i] = 1
for k in range ( 2 , K + 1 ):
for m in range ( 1 , N + 1 ):
dp[k][m] = 0
for i in range ( 1 , (N / / m) + 1 ):
dp[k][m] + = dp[k - 1 ][m * i]
ans = 0
for i in range ( 1 , N + 1 ):
ans + = dp[K][i]
return ans
if __name__ = = "__main__" :
N = 9
K = 5
print (countSequence(N, K))
|
C#
using System;
public class GFG
{
static int CountSequence( int N, int K)
{
int [,] dp = new int [K + 1, N + 1];
for ( int i = 1; i <= N; i++)
{
dp[1, i] = 1;
}
for ( int k = 2; k <= K; k++)
{
for ( int m = 1; m <= N; m++)
{
dp[k, m] = 0;
for ( int i = 1; i <= (N / m); i++)
{
dp[k, m] += dp[k - 1, m * i];
}
}
}
int ans = 0;
for ( int i = 1; i <= N; i++)
{
ans += dp[K, i];
}
return ans;
}
public static void Main( string [] args)
{
int N = 9;
int K = 5;
Console.WriteLine(CountSequence(N, K));
}
}
|
Javascript
function countSequence(N, K) {
let dp = new Array(K + 1);
for (let i = 0; i <= K; i++) {
dp[i] = new Array(N + 1);
}
for (let i = 1; i <= N; i++) {
dp[1][i] = 1;
}
for (let k = 2; k <= K; k++) {
for (let m = 1; m <= N; m++) {
dp[k][m] = 0;
for (let i = 1; i <= (N / m); i++) {
dp[k][m] += dp[k - 1][m * i];
}
}
}
let ans = 0;
for (let i = 1; i <= N; i++) {
ans += dp[K][i];
}
return ans;
}
let N = 9;
let K = 5;
console.log(countSequence(N, K));
|
Time Complexity: O(N*K*log N)
Auxiliary Space: O(N*K)
Share your thoughts in the comments
Please Login to comment...