Maximize the number of segments of length x, y and z

Last Updated : 10 Aug, 2026

Given an integer n denoting the Length of a line segment. You need to cut the line segment in such a way that the cut length of a line segment each time is either x , y or z. Here x, y, and z are integers. After performing all the cut operations, your total number of cut segments must be maximum. Return the maximum number of cut segments possible.

Note: if no segment can be cut then return 0.

Examples: 

Input: n = 4, x = 2, y = 1, z = 1
Output: 4
Explanation: Total length is 4, and the cut lengths are 2, 1 and 1.  We can make maximum 4 segments each of length 1.

Input: n = 5, x = 5, y = 3, z = 2
Output: 2
Explanation: Here total length is 5, and the cut lengths are 5, 3 and 2. We can make two segments of lengths 3 and 2.

Input: n = 7, x = 8, y = 9, z = 10
Output: 0
Explanation: Here the total length is 7, and the cut lengths are 8, 9, and 10. We cannot cut the segment into lengths that fully utilize the segment, so the output is 0.

Try It Yourself
redirect icon

[Naive Approach] Using Recursive Exploration - O(3 ^ n) Time and O(n) Space

The idea is to explore all possible ways to cut the rod by recursively subtracting each segment length. Base cases handle exact zero or negative length. Max cuts across all options gives answer.

At each step, we try all three possible cuts of length x, y, and z. Each node represents the remaining length of the rod, and the recursion continues until a valid or invalid base case is reached.

s
  • If n is zero, return 0
  • If n is negative, return -1
  • Recurse by subtracting x, y, and z separately
  • Find maximum among all three recursive results
  • If max is -1, return -1
  • Else return max + 1
C++
#include <algorithm>
#include <iostream>
using namespace std;

// Helper function to maximize the number
// of cuts using recursion
int maxCutHelper(int n, int x, int y, int z)
{

    // Base case: If the length is zero,
    // return zero cuts
    if (n == 0)
    {
        return 0;
    }

    // Base case: If the length becomes negative,
    // return an invalid result
    if (n < 0)
    {
        return -1;
    }

    // Recursive step: Try all three segment
    // lengths and choose the maximum result
    int cut1 = maxCutHelper(n - x, x, y, z);
    int cut2 = maxCutHelper(n - y, x, y, z);
    int cut3 = maxCutHelper(n - z, x, y, z);

    // Get the maximum number of cuts among
    // the 3 options
    int maxCut = max(cut1, max(cut2, cut3));

    // If no valid cut found, return negative
    //  value indicating no valid cuts
    if (maxCut == -1)
    {
        return -1;
    }

    return maxCut + 1;
}

// Main function to start the cutting process
int maximizeCuts(int n, int x, int y, int z)
{

    int res = maxCutHelper(n, x, y, z);

    // No valid cuts found
    if (res == -1)
        return 0;

    return res;
}

int main()
{

    int n = 4;
    int x = 2, y = 1, z = 1;

    cout << maximizeCuts(n, x, y, z);

    return 0;
}
Java
class GFG {

    // Helper function to maximize the number of cuts
    static int maxCutHelper(int n, int x, int y, int z) {

        // If rod length becomes exactly 0,
        // a valid set of cuts has been found
        if (n == 0) {
            return 0;
        }

        // If rod length becomes negative,
        // this path is invalid
        if (n < 0) {
            return -1;
        }

        // Try cutting lengths x, y, and z
        int cut1 = maxCutHelper(n - x, x, y, z);
        int cut2 = maxCutHelper(n - y, x, y, z);
        int cut3 = maxCutHelper(n - z, x, y, z);

        // Find the maximum cuts among the three choices
        int maxCut = Math.max(cut1, Math.max(cut2, cut3));

        // If all choices are invalid
        if (maxCut == -1) {
            return -1;
        }

        // Count the current cut
        return maxCut + 1;
    }

    // Function to find maximum number of cuts
    static int maximizeCuts(int n, int x, int y, int z) {

        int res = maxCutHelper(n, x, y, z);

        // If no valid cutting is possible
        return Math.max(0, res);
    }

    public static void main(String[] args) {

        int n = 4;

        int x = 2;
        int y = 1;
        int z = 1;

        int result = maximizeCuts(n, x, y, z);

        System.out.println(result);
    }
}
Python
def maxCutHelper(n, x, y, z):

    # Base case: If the length is zero, 
    # return zero cuts
    if n == 0:
        return 0

    # Base case: If the length becomes negative, 
    # return an invalid result
    if n < 0:
        return -1

    # Recursive step: Try all three segment 
    # lengths and choose the maximum result
    cut1 = maxCutHelper(n - x, x, y, z)
    cut2 = maxCutHelper(n - y, x, y, z)
    cut3 = maxCutHelper(n - z, x, y, z)

    # Get the maximum number of cuts among
    # the 3 options
    maxCut = max(cut1, cut2, cut3)

    # If no valid cut found, return negative
    # value indicating no valid cuts
    if maxCut == -1:
        return -1

    return maxCut + 1

def maximizeCuts(n, x, y, z):
  
    res = maxCutHelper(n, x, y, z)

    # No valid cuts found
    if res == -1:
        return 0

    return res

if __name__ == "__main__":

    n = 4
    x = 2
    y = 1
    z = 1

    print(maximizeCuts(n, x, y, z))
C#
using System;
class GFG {

    // Helper function to maximize the number
    // of cuts using recursion
    static int maxCutHelper(int n, int x, int y, int z) {

        // Base case: If the length is zero, 
        // return zero cuts
        if (n == 0) {
            return 0;
        }

        // Base case: If the length becomes negative, 
        // return an invalid result
        if (n < 0) {
            return -1; 
        }

        // Recursive step: Try all three segment 
        // lengths and choose the maximum result
        int cut1 = maxCutHelper(n - x, x, y, z);
        int cut2 = maxCutHelper(n - y, x, y, z);
        int cut3 = maxCutHelper(n - z, x, y, z);

        // Get the maximum number of cuts among
        // the 3 options
        int maxCut = Math.Max(cut1, Math.Max(cut2, cut3));

        // If no valid cut found, return negative
        // value indicating no valid cuts
        if (maxCut == -1) {
            return -1; 
        }

        return maxCut + 1;
    }

    static int maximizeCuts(int n, int x, int y, int z) {
      
        int res = maxCutHelper(n, x, y, z);

        // No valid cuts found
        if (res == -1) return 0;

        return res;
    }

    static void Main(string[] args) {

        int n = 4; 
        int x = 2, y = 1, z = 1;  

        Console.WriteLine(maximizeCuts(n, x, y, z));
    }
}
JavaScript
function maxCutHelper(n, x, y, z)
{

    // Base case: If the length is zero,
    // return zero cuts
    if (n === 0) {
        return 0;
    }

    // Base case: If the length becomes negative,
    // return an invalid result
    if (n < 0) {
        return -1;
    }

    // Recursive step: Try all three segment
    // lengths and choose the maximum result
    let cut1 = maxCutHelper(n - x, x, y, z);
    let cut2 = maxCutHelper(n - y, x, y, z);
    let cut3 = maxCutHelper(n - z, x, y, z);

    // Get the maximum number of cuts among
    // the 3 options
    let maxCut = Math.max(cut1, cut2, cut3);

    // If no valid cut found, return negative
    // value indicating no valid cuts
    if (maxCut === -1) {
        return -1;
    }

    return maxCut + 1;
}

function maximizeCuts(n, x, y, z)
{

    let res = maxCutHelper(n, x, y, z);

    // No valid cuts found
    if (res === -1)
        return 0;

    return res;
}

// Driver Code
let n = 4;
let x = 2;
let y = 1;
let z = 1;

console.log(maximizeCuts(n, x, y, z));

Output
4

[Better Approach] Using Top-Down DP with Memoization - O(n) Time and O(n) Space

If we take a closer look at the above recursion tree, we may observe overlapping subproblems like n-x-y and n-y-x are same.

The idea is to use memoization to avoid recomputing same subproblems. Store results for each length in memo array. Return maximum cuts possible.

Working of Approach:

  • Create a memo array where memo[i] stores the maximum number of segments possible for a rod of length i.
  • For each length n, recursively try all three cuts by subtracting x, y, and z.
  • If n becomes 0, return 0; if it becomes negative, return -1 to indicate an invalid cut.
  • Store each computed result in memo so that the same subproblem is not solved again.
  • Take the maximum result from the three choices and add 1; if no valid choice exists, return 0 for the original problem.
C++
#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;

// Helper function to maximize the number
// of cuts using recursion and memoization
int maxCutHelper(int n, int x, int y, int z,
                           vector<int>& memo) {
    
    // Base case: If the length is zero, 
    // return zero cuts
    if (n == 0) {
        return 0;
    }
    
    // Base case: If the length becomes negative, 
    // return an invalid result
    if (n < 0) {
        return -1; 
    }
    
    // If the result is already computed, 
    // return it from the memo array
    if (memo[n] != -1) {
        return memo[n];
    }
    
    // Recursive step: Try all three segment 
    // lengths and choose the maximum result
    int cut1 = maxCutHelper(n - x, x, y, z, memo);
    int cut2 = maxCutHelper(n - y, x, y, z, memo);
    int cut3 = maxCutHelper(n - z, x, y, z, memo);
    
    // Get the maximum number of cuts among
    // the 3 options
    int maxCut = max(cut1, max(cut2, cut3));
    
    // If no valid cut found, return negative
    // value indicating no valid cuts
    if (maxCut == -1) {
        return memo[n] = -1; 
    }
  
    return memo[n] = maxCut + 1;
}

int maximizeCuts(int n, int x, int y, int z) {
  
    // Create memoization array initialized to -1
    vector<int> memo(n + 1, -1);
  
    int res = maxCutHelper(n, x, y, z, memo); 
  
    // No valid cuts found
    if(res == -1) return 0;
  
    return res;
}

int main() {
    
    int n =4; 
    int x = 2, y = 1, z = 1;  

    cout << maximizeCuts(n, x, y, z);
    
    return 0;
}
Java
import java.util.Arrays;

class GFG {

    // Helper function using recursion + memoization
    static int maxCutHelper(int n, int x, int y, int z, int[] memo) {

        // Rod completely cut
        if (n == 0) {
            return 0;
        }

        // Invalid cut
        if (n < 0) {
            return -1;
        }

        // Return already computed result
        if (memo[n] != -1) {
            return memo[n];
        }

        // Try all three possible cuts
        int cut1 = maxCutHelper(n - x, x, y, z, memo);
        int cut2 = maxCutHelper(n - y, x, y, z, memo);
        int cut3 = maxCutHelper(n - z, x, y, z, memo);

        // Get maximum among the three choices
        int maxCut = Math.max(cut1, Math.max(cut2, cut3));

        // No valid cut possible
        if (maxCut == -1) {
            return memo[n] = -1;
        }

        return memo[n] = maxCut + 1;
    }

    static int maximizeCuts(int n, int x, int y, int z) {

        int[] memo = new int[n + 1];
        Arrays.fill(memo, -1);

        int res = maxCutHelper(n, x, y, z, memo);

        return Math.max(0, res);
    }

    public static void main(String[] args) {

        // Length of rod
        int n = 4;

        // Allowed cut lengths
        int x = 2;
        int y = 1;
        int z = 1;

        int result = maximizeCuts(n, x, y, z);

        System.out.println(result);
    }
}
Python
def maxCutHelper(n, x, y, z, memo):

    # Base case: If the length is zero, 
    # return zero cuts
    if n == 0:
        return 0

    # Base case: If the length becomes negative, 
    # return an invalid result
    if n < 0:
        return -1

    # If the result is already computed, 
    # return it from the memo dictionary
    if n in memo:
        return memo[n]

    # Recursive step: Try all three segment 
    # lengths and choose the maximum result
    cut1 = maxCutHelper(n - x, x, y, z, memo)
    cut2 = maxCutHelper(n - y, x, y, z, memo)
    cut3 = maxCutHelper(n - z, x, y, z, memo)

    # Get the maximum number of cuts among
    # the 3 options
    maxCut = max(cut1, cut2, cut3)

    # If no valid cut found, return negative
    # value indicating no valid cuts
    if maxCut == -1:
        memo[n] = -1
        return -1

    memo[n] = maxCut + 1
    return memo[n]

def maximizeCuts(n, x, y, z):
  
    # Create a memoization dictionary
    memo = {}

    res = maxCutHelper(n, x, y, z, memo)

    # No valid cuts found
    if res == -1:
        return 0

    return res

if __name__ == "__main__":

    n = 4
    x = 2
    y = 1
    z = 1

    print(maximizeCuts(n, x, y, z))
C#
using System;
using System.Collections.Generic;

class GFG {

    // Helper function to maximize the number
    // of cuts using recursion and memoization
    static int maxCutHelper(int n, int x, int y, 
                    int z, Dictionary<int, int> memo) {

        // Base case: If the length is zero, 
        // return zero cuts
        if (n == 0) {
            return 0;
        }

        // Base case: If the length becomes negative, 
        // return an invalid result
        if (n < 0) {
            return -1; 
        }

        // If the result is already computed, 
        // return it from the memo dictionary
        if (memo.ContainsKey(n)) {
            return memo[n];
        }

        // Recursive step: Try all three segment 
        // lengths and choose the maximum result
        int cut1 = maxCutHelper(n - x, x, y, z, memo);
        int cut2 = maxCutHelper(n - y, x, y, z, memo);
        int cut3 = maxCutHelper(n - z, x, y, z, memo);

        // Get the maximum number of cuts among
        // the 3 options
        int maxCut = Math.Max(cut1, Math.Max(cut2, cut3));

        // If no valid cut found, return negative
        // value indicating no valid cuts
        if (maxCut == -1) {
            memo[n] = -1;
            return -1; 
        }

        memo[n] = maxCut + 1;
        return memo[n];
    }

    static int maximizeCuts(int n, int x, int y, int z) {

        // Create a memoization dictionary
        var memo = new Dictionary<int, int>();

        int res = maxCutHelper(n, x, y, z, memo);

        // No valid cuts found
        if (res == -1) return 0;

        return res;
    }

    static void Main(string[] args) {

        int n = 4; 
        int x = 2, y = 1, z = 1;  

        Console.WriteLine(maximizeCuts(n, x, y, z));
    }
}
JavaScript
function maxCutHelper(n, x, y, z, memo)
{

    // Base case: If the length is zero,
    // return zero cuts
    if (n === 0) {
        return 0;
    }

    // Base case: If the length becomes negative,
    // return an invalid result
    if (n < 0) {
        return -1;
    }

    // If the result is already computed,
    // return it from the memo object
    if (n in memo) {
        return memo[n];
    }

    // Recursive step: Try all three segment
    // lengths and choose the maximum result
    let cut1 = maxCutHelper(n - x, x, y, z, memo);
    let cut2 = maxCutHelper(n - y, x, y, z, memo);
    let cut3 = maxCutHelper(n - z, x, y, z, memo);

    // Get the maximum number of cuts among
    // the 3 options
    let maxCut = Math.max(cut1, cut2, cut3);

    // If no valid cut found, return negative
    // value indicating no valid cuts
    if (maxCut === -1) {
        memo[n] = -1;
        return -1;
    }

    memo[n] = maxCut + 1;
    return memo[n];
}

function maximizeCuts(n, x, y, z)
{

    // Create a memoization object
    let memo = {};

    let res = maxCutHelper(n, x, y, z, memo);

    // No valid cuts found
    if (res === -1)
        return 0;

    return res;
}

// Driver Code
let n = 4;
let x = 2;
let y = 1;
let z = 1;

console.log(maximizeCuts(n, x, y, z));

Output
4

[Expected Approach] Using Bottom-Up DP - O(n) Time and O(n) Space

The idea is to build DP table from 1 to n. For each length, try all three possible cuts. If previous state is valid, update current state with max cuts.

Working of Approach:

  • Store the three possible cut lengths x, y, and z in an array and initialize dp with 0.
  • For each possible cut length, iterate through all rod lengths from 1 to n.
  • If the current length equals the cut length, one segment can be formed; otherwise, extend a previously formed valid length.
  • Update dp[i] with the maximum number of segments possible using the current cut.
  • After considering all three cut lengths, dp[n] gives the maximum number of segments.
C++
#include <algorithm>
#include <iostream>
#include <vector>
using namespace std;

int maximizeCuts(int n, int x, int y, int z)
{
    vector<int> arr(3);
    arr[0] = x;
    arr[1] = y;
    arr[2] = z;

    // creating a dp[] array and initializing all values with 0.
    vector<int> dp(n + 1, 0);

    for (int j = 0; j < 3; j++)
    {

        // updating the point where we can reach from x,y,z.
        for (int i = 1; i <= n; i++)
        {

            // we will update dp[i] if the point is x,y,z or if the
            // points are visited by some combination of x,y,z.
            if (i == arr[j] or (i > arr[j] and dp[i - arr[j]] > 0))
                dp[i] = max(dp[i - arr[j]] + 1, dp[i]);
        }
    }

    // returning the result.
    return dp[n];
}

int main()
{

    int n = 4;
    int x = 2, y = 1, z = 1;

    cout << maximizeCuts(n, x, y, z);

    return 0;
}
Java
import java.util.Arrays;

public class GFG {
    public static int maximizeCuts(int n, int x, int y,
                                   int z)
    {
        int[] arr = { x, y, z };

        // creating a dp[] array and initializing all values
        // with 0.
        int[] dp = new int[n + 1];
        Arrays.fill(dp, 0);

        for (int j = 0; j < 3; j++) {

            // updating the point where we can reach from
            // x,y,z.
            for (int i = 1; i <= n; i++) {

                // we will update dp[i] if the point is
                // x,y,z or if the points are visited by
                // some combination of x,y,z.
                if (i == arr[j]
                    || (i > arr[j] && dp[i - arr[j]] > 0))
                    dp[i] = Math.max(dp[i - arr[j]] + 1,
                                     dp[i]);
            }
        }

        // returning the result.
        return dp[n];
    }

    public static void main(String[] args)
    {
        int n = 4;
        int x = 2, y = 1, z = 1;

        System.out.println(maximizeCuts(n, x, y, z));
    }
}
Python
def maximizeCuts(n, x, y, z):
    arr = [x, y, z]

    # creating a dp[] array and initializing all values with 0.
    dp = [0] * (n + 1)

    for j in range(3):

        # updating the point where we can reach from x,y,z.
        for i in range(1, n + 1):

            # we will update dp[i] if the point is x,y,z or if the
            # points are visited by some combination of x,y,z.
            if i == arr[j] or (i > arr[j] and dp[i - arr[j]] > 0):
                dp[i] = max(dp[i - arr[j]] + 1, dp[i])

    # returning the result.
    return dp[n]

if __name__ == '__main__':
    n = 4
    x = 2; y = 1; z = 1

    print(maximizeCuts(n, x, y, z))
C#
using System;

public class GFG {
    public static int maximizeCuts(int n, int x, int y,
                                   int z)
    {
        int[] arr = { x, y, z };

        // creating a dp[] array and initializing all values
        // with 0.
        int[] dp = new int[n + 1];

        for (int j = 0; j < 3; j++) {

            // updating the point where we can reach from
            // x,y,z.
            for (int i = 1; i <= n; i++) {

                // we will update dp[i] if the point is
                // x,y,z or if the points are visited by
                // some combination of x,y,z.
                if (i == arr[j]
                    || (i > arr[j] && dp[i - arr[j]] > 0))
                    dp[i] = Math.Max(dp[i - arr[j]] + 1,
                                     dp[i]);
            }
        }

        // returning the result.
        return dp[n];
    }

    public static void Main()
    {
        int n = 4;
        int x = 2, y = 1, z = 1;

        Console.WriteLine(maximizeCuts(n, x, y, z));
    }
}
JavaScript
function maximizeCuts(n, x, y, z)
{
    let arr = [ x, y, z ];

    // creating a dp[] array and initializing all values
    // with 0.
    let dp = new Array(n + 1).fill(0);

    for (let j = 0; j < 3; j++) {

        // updating the point where we can reach from x,y,z.
        for (let i = 1; i <= n; i++) {

            // we will update dp[i] if the point is x,y,z or
            // if the points are visited by some combination
            // of x,y,z.
            if (i === arr[j]
                || (i > arr[j] && dp[i - arr[j]] > 0))
                dp[i] = Math.max(dp[i - arr[j]] + 1, dp[i]);
        }
    }

    // returning the result.
    return dp[n];
}

// Driver Code
let n = 4;
let x = 2, y = 1, z = 1;

console.log(maximizeCuts(n, x, y, z));

Output
4
Comment