Open In App

Sequences of given length where every element is more than or equal to twice of previous

Last Updated : 03 Jan, 2025
Comments
Improve
Suggest changes
Like Article
Like
Report

Given two integers n and m, the task is to determine the total number of special sequences of length n such that:

  • seq[i+1] >= 2 * seq[i]
  • seq[i] > 0
  • seq[i] <= m

Examples :

Input: n = 4, m = 10
Output: 4
Explanation: The sequences are [1, 2, 4, 8], [1, 2, 4, 9], [1, 2, 4, 10], [1, 2, 5, 10]

Input: n = 2, m = 5
Output: 6
Explanation: The sequences are [1, 2], [1, 3], [1, 4], [1, 5], [2, 4], [2, 5]

Using Recursion - O(2^max(n, m)) Time and O(2^max(n, m)) Space

We can easily identify the recursive nature of this problem. To form a special sequence of length n with a maximum value m, we have two choices:

  • Exclude the current value m and solve for the same length n with m-1.
  • Include the current value m (if valid) and solve for the reduced length n-1 with the new maximum value m/2.

Thus, for each state (n, m), the total number of special sequences can be obtained using the following recurrence relation:

numberSequence(n, m) = numberSequence(n, m-1) + numberSequence(n-1, m/2)

C++
// C++ program to count the number of special sequences
// of length n using Recursion

#include <iostream>
using namespace std;

int numberSequence(int n, int m) {

    // Base case 1: If the sequence length (n) is 0,
    // we have a valid sequence
    if (n == 0)
        return 1;

    // Base case 2: If the maximum value (m) is 0,
    // no sequences can be formed
    else if (m == 0)
        return 0;

    // Recursive case:
    // 1. Exclude the current value (m):
    // 		Move to the next smaller value (m-1)
    // 2. Include the current value (m):
    //    	Use m / 2 as the next upper bound for the
    //    	sequence
    else
        return 	numberSequence(n, m - 1) + 
      			numberSequence(n - 1, m / 2);
}

int main() {
    int n = 4, m = 10;
    cout << numberSequence(n, m) << endl;
    return 0;
}
Java
// Java program to count the number of special sequences
// of length n using Recursion

class GfG {
    
    static int numberSequence(int n, int m) {
        
        // Base case 1: If the sequence length (n) is 0,
        // we have a valid sequence
        if (n == 0) {
            return 1;
        }
        
        // Base case 2: If the maximum value (m) is 0,
        // no sequences can be formed
        else if (m == 0) {
            return 0;
        }
        
        // Recursive case:
        // 1. Exclude the current value (m):
        //    Move to the next smaller value (m-1)
        // 2. Include the current value (m):
        //    Use m / 2 as the next upper bound for the sequence
        else {
            return 	numberSequence(n, m - 1) + 
              		numberSequence(n - 1, m / 2);
        }
    }
    
    public static void main(String[] args) {
        int n = 4;
        int m = 10;
        System.out.println(numberSequence(n, m));
    }
}
Python
# Python program to count the number of special sequences
# of length n using Recursion

def numberSequence(n: int, m: int) -> int:

    # Base case 1: If the sequence length (n) is 0,
    # we have a valid sequence
    if n == 0:
        return 1

    # Base case 2: If the maximum value (m) is 0,
    # no sequences can be formed
    elif m == 0:
        return 0

    # Recursive case:
    # 1. Exclude the current value (m):
    #    Move to the next smaller value (m-1)
    # 2. Include the current value (m):
    #    Use m // 2 as the next upper bound for the sequence
    else:
        return numberSequence(n, m - 1) + numberSequence(n - 1, m // 2)

if __name__ == "__main__":
    n, m = 4, 10
    print(numberSequence(n, m))
C#
// C# program to count the number of special sequences
// of length n using Recursion

using System;

class GfG {
    static int numberSequence(int n, int m) {
      
        // Base case 1: If the sequence length (n) is 0,
        // we have a valid sequence
        if (n == 0)
            return 1;

        // Base case 2: If the maximum value (m) is 0,
        // no sequences can be formed
        else if (m == 0)
            return 0;

        // Recursive case:
        // 1. Exclude the current value (m):
        //    Move to the next smaller value (m - 1)
        // 2. Include the current value (m):
        //    Use m / 2 as the next upper bound for the sequence
        else
            return 	numberSequence(n, m - 1) + 
          			numberSequence(n - 1, m / 2);
    }

    static public void Main() {
        int n = 4;
        int m = 10;
        Console.WriteLine(numberSequence(n, m));
    }
}
JavaScript
// JavaScript program to count the number of special sequences
// of length n using Recursion

function numberSequence(n, m) {

    // Base case 1: If the sequence length (n) is 0,
    // we have a valid sequence
    if (n === 0) {
        return 1;
    }
    
    // Base case 2: If the maximum value (m) is 0,
    // no sequences can be formed
    else if (m === 0) {
        return 0;
    }
    
    // Recursive case:
    // 1. Exclude the current value (m):
    //    Move to the next smaller value (m - 1)
    // 2. Include the current value (m):
    //    Use Math.floor(m / 2) as the next upper bound for the sequence
    else {
        return 	numberSequence(n, m - 1) + 
        		numberSequence(n - 1, Math.floor(m / 2));
    }
}

// Driver code
const n = 4;
const m = 10;
console.log(numberSequence(n, m));

Output
4

Using Top Down DP (Memoization) - O(n * m) Time and O(n * m) Space

If we carefully analyse the recursive solution, we can observe that the problem satisfies the following two properties of Dynamic Programming:

1. Optimal Substructure: The total number of special sequences of length n with a maximum value m depends on two subproblems:

  • Excluding the current value m → Solved by numberSequence(n, m-1)
  • Including the current value m → Solved by numberSequence(n-1, m/2)

By combining these optimal solutions of the subproblems, we can compute the result for the original problem.

2. Overlapping Subproblems: In the recursive approach, we notice that the same subproblems are solved multiple times. For example, in the given image, f(3, 4) is computed more than once when solving for f(4, 10). This redundancy leads to overlapping subproblems, increasing the time complexity.

By storing the results of previously solved subproblems, we can avoid redundant computations and optimize the solution.

1
Overlapping Subproblems in Sequence of Sequences
  • There are two parameters that change in the recursive solution: n and m. Both can range from 0 to their respective values. To optimize the recursive solution, we use memoization with a 2D array memo[][] of size (n+1)×(m+1).
  • This memo[][] is initialized with -1, indicating that no subproblem has been computed initially.
  • Now we modify our recursive solution to first check if the value is -1, then only make recursive calls. This way, we avoid re-computations of the same subproblems.
  • Therefore, final answer would be stored in memo[n][m].
C++
// C++ program to count the number of special sequences
// of length n using Memoization

#include <iostream>
#include <vector>
using namespace std;

int helper(int n, int m, vector<vector<int>> &memo) {

    // Base case 1: If the sequence length (n) is 0,
    // we have a valid sequence
    if (n == 0)
        return 1;

    // Base case 2: If the maximum value (m) is 0,
    // no sequences can be formed
    else if (m == 0)
        return 0;

    // If the result is already computed,
    // return the stored value
    else if (memo[n][m] != -1)
        return memo[n][m];

    // Recursive case:
    // 1. Exclude the current value (m):
    // 		Move to the next smaller value (m-1)
    // 2. Include the current value (m):
    //    	Use m / 2 as the next upper bound for the
    //    	sequence
    else
        return memo[n][m] = helper(n, m - 1, memo) +
                            helper(n - 1, m / 2, memo);
}

int numberSequence(int n, int m) {
    vector<vector<int>> memo(n + 1, vector<int>(m + 1, -1));
    return helper(n, m, memo);
}

int main() {
    int n = 4, m = 10;
    cout << numberSequence(n, m) << endl;

    return 0;
}
Java
// Java program to count the number of special sequences
// of length n using Memoization

class GfG {
    static int helper(int n, int m, int[][] memo) {
      
        // Base case 1: If the sequence length (n) is 0,
        // we have a valid sequence
        if (n == 0) {
            return 1;
        }

        // Base case 2: If the maximum value (m) is 0,
        // no sequences can be formed
        if (m == 0) {
            return 0;
        }

        // If the result is already computed, return the stored value
        if (memo[n][m] != -1) {
            return memo[n][m];
        }

        // Recursive case:
        // 1. Exclude the current value (m):
        //    Move to the next smaller value (m-1)
        // 2. Include the current value (m):
        //    Use m / 2 as the next upper bound for the sequence
        int excludeCurrent = helper(n, m - 1, memo);
        int includeCurrent = helper(n - 1, m / 2, memo);

        // Store the computed result in the memoization table
        memo[n][m] = excludeCurrent + includeCurrent;

        return memo[n][m];
    }

    static int numberSequence(int n, int m) {
        int[][] memo = new int[n + 1][m + 1];
        for (int i = 0; i <= n; i++) {
            for (int j = 0; j <= m; j++) {
                memo[i][j] = -1;
            }
        }

        return helper(n, m, memo);
    }

    public static void main(String[] args) {
        int n = 4;
        int m = 10;
        System.out.println(numberSequence(n, m)); 
    }
}
Python
# Python program to count the number of special sequences
# of length n using Memoization

def helper(n: int, m: int, memo: list) -> int:
  
    # Base case 1: If the sequence length (n) is 0,
    # we have a valid sequence
    if n == 0:
        return 1

    # Base case 2: If the maximum value (m) is 0,
    # no sequences can be formed
    if m == 0:
        return 0

    # If the result is already computed, return the stored value
    if memo[n][m] != -1:
        return memo[n][m]

    # Recursive case:
    # 1. Exclude the current value (m):
    #    Move to the next smaller value (m-1)
    # 2. Include the current value (m):
    #    Use m // 2 as the next upper bound for the sequence
    exclude_current = helper(n, m - 1, memo)
    include_current = helper(n - 1, m // 2, memo)

    # Store the computed result in the memoization table
    memo[n][m] = exclude_current + include_current

    return memo[n][m]

def numberSequence(n: int, m: int) -> int:
    memo = [[-1 for _ in range(m + 1)] for _ in range(n + 1)]
    return helper(n, m, memo)


if __name__ == "__main__":
    n = 4
    m = 10
    print(numberSequence(n, m))
C#
// C# program to count the number of special sequences
// of length n using Memoization
using System;

class GfG {
  
    // Helper function to calculate the total number of special
    // sequences using memoization to avoid redundant calculations
    static int Helper(int n, int m, int[,] memo) {
      
        // Base case 1: If the sequence length (n) is 0,
        // we have a valid sequence
        if (n == 0)
            return 1;

        // Base case 2: If the maximum value (m) is 0,
        // no sequences can be formed
        if (m == 0)
            return 0;

        // If the result is already computed,
        // return the stored value
        if (memo[n, m] != -1)
            return memo[n, m];

        // Recursive case:
        // 1. Exclude the current value (m):
        //    Move to the next smaller value (m-1)
        // 2. Include the current value (m):
        //    Use m / 2 as the next upper bound for the sequence
        memo[n, m] = Helper(n, m - 1, memo) + Helper(n - 1, m / 2, memo);
        return memo[n, m];
    }

    static int NumberSequence(int n, int m) {
        int[,] memo = new int[n + 1, m + 1];
        for (int i = 0; i <= n; i++)
            for (int j = 0; j <= m; j++)
                memo[i, j] = -1;

        return Helper(n, m, memo);
    }

    static public void Main() {
        int n = 4, m = 10;
        Console.WriteLine(NumberSequence(n, m));
    }
}
JavaScript
// JavaScript program to count the number of special sequences
// of length n using Memoization

function helper(n, m, memo) {

    // Base case 1: If the sequence length (n) is 0,
    // we have a valid sequence
    if (n === 0) {
        return 1;
    }

    // Base case 2: If the maximum value (m) is 0,
    // no sequences can be formed
    if (m === 0) {
        return 0;
    }

    // If the result is already computed, return the stored value
    if (memo[n][m] !== -1) {
        return memo[n][m];
    }

    // Recursive case:
    // 1. Exclude the current value (m):
    //    Move to the next smaller value (m-1)
    // 2. Include the current value (m):
    //    Use Math.floor(m / 2) as the next upper bound for the sequence
    const excludeCurrent = helper(n, m - 1, memo);
    const includeCurrent = helper(n - 1, Math.floor(m / 2), memo);

    // Store the computed result in the memoization table
    memo[n][m] = excludeCurrent + includeCurrent;

    return memo[n][m];
}
function numberSequence(n, m) {
    const memo = Array.from({ length: n + 1 }, () => Array(m + 1).fill(-1));
    return helper(n, m, memo);
}

// Driver Code
const n = 4;
const m = 10;
console.log(numberSequence(n, m));

Output
4

Using Bottom Up DP (Tabulation) - O(n * m) Time and O(n * m) Space

The approach is similar to the recursive one; however, instead of breaking down the problem recursively, we iteratively build up the solution in a bottom-up manner using a DP table. We maintain a dp[][] table such that dp[i][j] stores the total number of special sequences of length i with the maximum value j.

Base Case:

  • For i = 0 (sequence length 0), dp[0][j] = 1 for all j, as there is exactly one empty sequence.
  • For j = 0 (maximum value 0), dp[i][0] = 0 for all i > 0, as no valid sequence can be formed.

Recursive Case:

  • For i > 0 and j > 0, dp[i][j] = dp[i][j-1] + dp[i-1][j/2]

dp[i][j-1] represents excluding the current value j. dp[i-1][j/2] represents including the current value j and reducing the next allowable maximum to j/2. By iteratively calculating these values, we build the solution in a bottom-up manner and find the result in dp[n][m].

C++
// C++ program to count the number of special sequences
// of length n using Tabulation

#include <iostream>
#include <vector>
using namespace std;

int numberSequence(int n, int m) {
    vector<vector<int>> dp(n + 1, vector<int>(m + 1, -1));

    for (int i = 0; i <= n; i++) {
        for (int j = 0; j <= m; j++) {
          
            // Base case 1: If the sequence length (n) is 0,
            // we have a valid sequence
            if (i == 0)
                dp[i][j] = 1;

            // Base case 2: If the maximum value (m) is 0,
            // no sequences can be formed
            else if (j == 0)
                dp[i][j] = 0;

            // Transition:
            // 1. Exclude the current value j
            //      Use dp[i][j - 1]
            // 2. Include the current value j
            //      Use dp[i - 1][j / 2]
            else
                dp[i][j] = dp[i][j - 1] + dp[i - 1][j / 2];
        }
    }

    return dp[n][m];
}

int main() {
    int n = 4, m = 10;
    cout << numberSequence(n, m) << endl;
    return 0;
}
Java
// Java program to count the number of special sequences
// of length n using Tabulation

class GfG {
    static int numberSequence(int n, int m) {
        int[][] dp = new int[n + 1][m + 1];

        for (int i = 0; i <= n; i++) {
            for (int j = 0; j <= m; j++) {

                // Base case 1: If the sequence length (i)
                // is 0, we have exactly one valid sequence:
                // the empty sequence
                if (i == 0) {
                    dp[i][j] = 1;
                }

                // Base case 2: If the maximum value (j) is
                // 0 and i > 0, no valid sequences can be
                // formed
                else if (j == 0) {
                    dp[i][j] = 0;
                }

                // Recursive case:
                // 1. Exclude the current value j:
                //    The number of sequences is the same as
                //    sequences of length i with maximum j-1
                // 2. Include the current value j:
                //    The number of sequences is the same as
                //    sequences of length i-1 with maximum
                //    floor(j/2)
                else {
                    dp[i][j]
                        = dp[i][j - 1] + dp[i - 1][j / 2];
                }
            }
        }

        return dp[n][m];
    }

    public static void main(String[] args) {
        int n = 4;
        int m = 10;
        System.out.println(numberSequence(n, m));
    }
}
Python
# Python program to count the number of special sequences
# of length n using Tabulation

def numberSequence(n: int, m: int) -> int:
    dp = [[-1 for _ in range(m + 1)] for _ in range(n + 1)]

    for i in range(n + 1):
        for j in range(m + 1):
          
            # Base case 1: If the sequence length (i) is 0,
            # we have exactly one valid sequence: the empty sequence
            if i == 0:
                dp[i][j] = 1
                
            # Base case 2: If the maximum value (j) is 0 and i > 0,
            # no valid sequences can be formed
            elif j == 0:
                dp[i][j] = 0
                
            # Recursive case:
            # 1. Exclude the current value j:
            #    The number of sequences is the same as sequences of length i with maximum j-1
            # 2. Include the current value j:
            #    The number of sequences is the same as sequences of length i-1 with maximum floor(j/2)
            else:
                dp[i][j] = dp[i][j - 1] + dp[i - 1][j // 2]

    return dp[n][m]

if __name__ == "__main__":
    n = 4
    m = 10
    print(numberSequence(n, m))
C#
// C# program to count the number of special sequences
// of length n using Tabulation

using System;

class GfG {
    static int NumberSequence(int n, int m) {
        int[,] dp = new int[n + 1, m + 1];

        for (int i = 0; i <= n; i++) {
            for (int j = 0; j <= m; j++) {
              
                // Base case 1: If the sequence length (n) is 0,
                // we have a valid sequence
                if (i == 0)
                    dp[i, j] = 1;

                // Base case 2: If the maximum value (m) is 0,
                // no sequences can be formed
                else if (j == 0)
                    dp[i, j] = 0;

                // Transition:
                // 1. Exclude the current value j
                //    Use dp[i, j - 1]
                // 2. Include the current value j
                //    Use dp[i - 1, j / 2]
                else
                    dp[i, j] = dp[i, j - 1] + dp[i - 1, j / 2];
            }
        }

        return dp[n, m];
    }

    static public void Main() {
        int n = 4, m = 10;
        Console.WriteLine(NumberSequence(n, m));
    }
}
JavaScript
// JavaScript program to count the number of special
// sequences of length n using Tabulation

function numberSequence(n, m) {
    const dp = Array.from({length : n + 1},
                          () => Array(m + 1).fill(-1));

    for (let i = 0; i <= n; i++) {
        for (let j = 0; j <= m; j++) {

            // Base case 1: If the sequence length (i) is 0,
            // we have exactly one valid sequence: the empty
            // sequence
            if (i === 0) {
                dp[i][j] = 1;
            }

            // Base case 2: If the maximum value (j) is 0
            // and i > 0, no valid sequences can be formed
            else if (j === 0) {
                dp[i][j] = 0;
            }

            // Recursive case:
            // 1. Exclude the current value j:
            //    The number of sequences is the same as
            //    sequences of length i with maximum j-1
            // 2. Include the current value j:
            //    The number of sequences is the same as
            //    sequences of length i-1 with maximum
            //    floor(j/2)
            else {
                dp[i][j] = dp[i][j - 1]
                           + dp[i - 1][Math.floor(j / 2)];
            }
        }
    }

    return dp[n][m];
}

// Driver Code
const n = 4;
const m = 10;
console.log(numberSequence(n, m));

Output
4

Using Space Optimized DP - O(n * m) Time and O(m) Space

In the above approach, we observe that each subproblem only depends on the results of the previous row, that is, dp[i][j] depends on values from dp[i-1][j/2] and the current row dp[i][j-1]. Therefore, we can optimize the space complexity by using just two 1D arrays to store the results for the current and previous rows.

C++
// C++ program to count the number of special sequences
// of length n using Space Optimized DP

#include <iostream>
#include <vector>
using namespace std;

int numberSequence(int n, int m) {

    // Use two 1D arrays (prev and curr) to store results
    // for two consecutive rows
    vector<int> prev(m + 1), curr(m + 1);

    for (int i = 0; i <= n; i++) {
        for (int j = 0; j <= m; j++) {

            // Base case 1: If the sequence length (n) is 0,
            // we have a valid sequence
            if (i == 0)
                curr[j] = 1;

            // Base case 2: If the maximum value (m) is 0,
            // no sequences can be formed
            else if (j == 0)
                curr[j] = 0;

            // Transition:
            // 1. Exclude the current value j
            //      Use curr[j - 1]
            // 2. Include the current value j
            //      Use prev[j / 2]
            else
                curr[j] = curr[j - 1] + prev[j / 2];
        }

        // Move current row to previous row for the next
        // iteration
        prev = curr;
    }
  
    return prev[m];
}

int main() {
    int n = 4, m = 10;
    cout << numberSequence(n, m) << endl;

    return 0;
}
Java
// Java program to count the number of special sequences
// of length n using Space Optimized DP

class GfG {
    static int numberSequence(int n, int m) {

        // Initialize two 1D arrays (prev and curr) with
        // size m + 1 prev[j] represents dp[i-1][j] and
        // curr[j] represents dp[i][j]
        int[] prev = new int[m + 1];
        int[] curr = new int[m + 1];

        for (int i = 0; i <= n; i++) {
            for (int j = 0; j <= m; j++) {

                // Base case 1: If the sequence length (i)
                // is 0, there is exactly one valid
                // sequence: the empty sequence
                if (i == 0) {
                    curr[j] = 1;
                }
              
                // Base case 2: If the maximum value (j) is
                // 0 and i > 0, no valid sequences can be
                // formed
                else if (j == 0) {
                    curr[j] = 0;
                }
              
                // Recursive case:
                // 1. Exclude the current value j:
                //    The number of sequences is the same as
                //    sequences of length i with maximum j-1
                // 2. Include the current value j:
                //    The number of sequences is the same as
                //    sequences of length i-1 with maximum
                //    floor(j/2)
                else {
                  
                    // Ensure that j >= 1 to prevent
                    // IndexOutOfBounds Since j > 0 in this
                    // else block, j-1 is always valid
                    curr[j] = curr[j - 1] + prev[j / 2];
                }
            }

            // Move current row to previous row for the next
            // iteration
            prev = (int[])(curr.clone());
        }

        return prev[m];
    }

    public static void main(String[] args) {
        int n = 4;
        int m = 10;
        System.out.println(numberSequence(n, m));
    }
}
Python
# Python program to count the number of special sequences
# of length n using Space Optimized DP

def numberSequence(n: int, m: int) -> int:
  
    # Initialize two 1D lists (prev and curr) with size m + 1
    prev = [0] * (m + 1)
    curr = [0] * (m + 1)

    for i in range(n + 1):
        for j in range(m + 1):
          
            # Base case 1: If the sequence length (i) is 0,
            # there is exactly one valid sequence: the empty sequence
            if i == 0:
                curr[j] = 1
                
            # Base case 2: If the maximum value (j) is 0 and i > 0,
            # no valid sequences can be formed
            elif j == 0:
                curr[j] = 0
                
            # Recursive case:
            # 1. Exclude the current value j:
            #    The number of sequences is the same as sequences of length i with maximum j-1
            # 2. Include the current value j:
            #    The number of sequences is the same as sequences of length i-1 with maximum floor(j/2)
            else:
                curr[j] = curr[j - 1] + prev[j // 2]
                
        # After processing the current row, copy curr to prev for the next iteration
        prev = curr.copy()

    return prev[m]

if __name__ == "__main__":
    n = 4
    m = 10
    print(numberSequence(n, m))
C#
// C# program to count the number of special sequences
// of length n using Space Optimized DP
using System;

class GfG {
    static int numberSequence(int n, int m) {
      
        // Use two 1D arrays (prev and curr) to store results
        // for two consecutive rows
        int[] prev = new int[m + 1];
        int[] curr = new int[m + 1];

        for (int i = 0; i <= n; i++) {
            for (int j = 0; j <= m; j++) {
              
                // Base case 1: If the sequence length (n) is 0,
                // we have a valid sequence
                if (i == 0)
                    curr[j] = 1;

                // Base case 2: If the maximum value (m) is 0,
                // no sequences can be formed
                else if (j == 0)
                    curr[j] = 0;

                // Transition:
                // 1. Exclude the current value j
                //    Use curr[j - 1]
                // 2. Include the current value j
                //    Use prev[j / 2]
                else
                    curr[j] = curr[j - 1] + prev[j / 2];
            }

            // Move current row to previous row for the next iteration
            Array.Copy(curr, prev, m + 1);
        }
        return prev[m];
    }

    static public void Main() {
        int n = 4, m = 10;
        Console.WriteLine(numberSequence(n, m));
    }
}
JavaScript
// JavaScript program to count the number of special
// sequences of length n using Space Optimized DP

function numberSequence(n, m) {

    // Initialize two 1D arrays (prev and curr) with size m
    // + 1 prev[j] represents dp[i-1][j] and curr[j]
    // represents dp[i][j]
    let prev = new Array(m + 1).fill(0);
    let curr = new Array(m + 1).fill(0);

    for (let i = 0; i <= n; i++) {
        for (let j = 0; j <= m; j++) {

            // Base case 1: If the sequence length (i) is 0,
            // there is exactly one valid sequence: the
            // empty sequence
            if (i === 0) {
                curr[j] = 1;
            }

            // Base case 2: If the maximum value (j) is 0
            // and i > 0, no valid sequences can be formed
            else if (j === 0) {
                curr[j] = 0;
            }

            // Recursive case:
            // 1. Exclude the current value j:
            //    The number of sequences is the same as
            //    sequences of length i with maximum j-1
            // 2. Include the current value j:
            //    The number of sequences is the same as
            //    sequences of length i-1 with maximum
            //    floor(j/2)
            else {
            
                // Ensure that j >= 1 to prevent
                // IndexOutOfBounds Since j > 0 in this else
                // block, j-1 is always valid
                const excludeCurrent = curr[j - 1];
                const includeCurrent
                    = prev[Math.floor(j / 2)];
                curr[j] = excludeCurrent + includeCurrent;
            }
        }

        // After processing the current row, copy curr to
        // prev for the next iteration This is essential for
        // space optimization, as we only keep track of the
        // previous row
        prev = [...curr ];
    }

    return prev[m];
}

// Driver Code
const n = 4;
const m = 10;
console.log(numberSequence(n, m));

Output
4

Next Article

Similar Reads