Maximum Product Cutting

Last Updated : 16 May, 2026

Given a rope of length n meters, cut the rope in different parts of integer lengths in a way that maximizes product of lengths of all parts. You must make at least one cut. Assume that the length of rope is more than 2 meters. 

Examples: 

Input: n = 2
Output: 1
Explanation: Maximum obtainable product is 1 * 1 = 1

Input: n = 3
Output: 6
Explanation: You can cut rope into following ways:
1 * 1 * 1 = 1
1 * 2 = 2
2 * 1 = 2
Maximum obtainable product is 1 * 2 = 2 = 2 * 1

Try It Yourself
redirect icon

[Naive Approach] Using Recursion - O(2 ^ n) Time and O(n) Space

This problem is similar to Rod Cutting Problem. We can get the maximum product by making a cut at different positions and comparing the values obtained after a cut. We can recursively call the same function for a piece obtained after a cut.

  • We try cutting the rope at every possible position from 1 to n - 1.
  • For every cut, we calculate two possibilities: directly multiply the two rope parts, or further divide the remaining rope recursively.
  • The recursive function keeps exploring all possible cuts to find the maximum product.
  • At every step, we store the maximum product obtained so far in maxValue.
  • Finally, the function returns the maximum product possible after cutting the rope.
C++
#include <iostream>
using namespace std;

int maxProduct(int n)
{
    // Base Case
    // Rope of length 0 or 1
    // cannot be further divided
    if (n == 0 || n == 1)
    {
        return 0;
    }

    // Store maximum product
    int maxValue = 0;

    // Try every possible cut
    for (int i = 1; i < n; i++)
    {
        // 1. Cut rope into two parts
        int directProduct = i * (n - i);

        // 2. Further divide remaining part
        int recursiveProduct = i * maxProduct(n - i);

        // Store maximum product
        maxValue = max(maxValue, max(directProduct, recursiveProduct));
    }

    return maxValue;
}

// Driver Code
int main()
{
    int n = 10;
    cout << "Maximum Product is " << maxProduct(n);

    return 0;
}
C
#include <stdio.h>

// Utility function to return maximum
int max(int a, int b)
{
    return (a > b) ? a : b;
}

int maxProduct(int n)
{
    // Base Case
    // Rope of length 0 or 1
    // cannot be further divided
    if (n == 0 || n == 1)
    {
        return 0;
    }

    // Store maximum product
    int maxValue = 0;

    // Try every possible cut
    for (int i = 1; i < n; i++)
    {
        // 1. Cut rope into two parts
        int directProduct = i * (n - i);

        // 2. Further divide remaining part
        int recursiveProduct = i * maxProduct(n - i);

        // Store maximum product
        maxValue = max(maxValue, max(directProduct, recursiveProduct));
    }

    return maxValue;
}

// Driver Code
int main()
{
    int n = 10;
    printf("Maximum Product is %d", maxProduct(n));

    return 0;
}
Java
class GFG {
    static int maxProduct(int n)
    {
        // Base Case
        // Rope of length 0 or 1
        // cannot be further divided
        if (n == 0 || n == 1) {
            return 0;
        }

        // Store maximum product
        int maxValue = 0;

        // Try every possible cut
        for (int i = 1; i < n; i++) {
            // 1. Cut rope into two parts
            int directProduct = i * (n - i);

            // 2. Further divide remaining part
            int recursiveProduct = i * maxProduct(n - i);

            // Store maximum product
            maxValue = Math.max(
                maxValue,
                Math.max(directProduct, recursiveProduct));
        }

        return maxValue;
    }

    // Driver Code
    public static void main(String[] args)
    {
        int n = 10;
        System.out.println("Maximum Product is "
                           + maxProduct(n));
    }
}
Python
def maxProduct(n):

    # Base Case
    # Rope of length 0 or 1
    # cannot be further divided
    if n == 0 or n == 1:
        return 0

    # Store maximum product
    maxValue = 0

    # Try every possible cut
    for i in range(1, n):

        # 1. Cut rope into two parts
        directProduct = i * (n - i)

        # 2. Further divide remaining part
        recursiveProduct = i * maxProduct(n - i)

        # Store maximum product
        maxValue = max(
            maxValue,
            max(directProduct, recursiveProduct)
        )

    return maxValue


# Driver Code
if __name__ == "__main__":
    n = 10

    print("Maximum Product is",
          maxProduct(n))
C#
using System;

class GFG {
    static int maxProduct(int n)
    {
        // Base Case
        // Rope of length 0 or 1
        // cannot be further divided
        if (n == 0 || n == 1) {
            return 0;
        }

        // Store maximum product
        int maxValue = 0;

        // Try every possible cut
        for (int i = 1; i < n; i++) {
            // 1. Cut rope into two parts
            int directProduct = i * (n - i);

            // 2. Further divide remaining part
            int recursiveProduct = i * maxProduct(n - i);

            // Store maximum product
            maxValue = Math.Max(
                maxValue,
                Math.Max(directProduct, recursiveProduct));
        }

        return maxValue;
    }

    // Driver Code
    static void Main()
    {
        int n = 10;
        Console.WriteLine("Maximum Product is "
                          + maxProduct(n));
    }
}
JavaScript
function maxProduct(n)
{
    // Base Case
    // Rope of length 0 or 1
    // cannot be further divided
    if (n === 0 || n === 1) {
        return 0;
    }

    // Store maximum product
    let maxValue = 0;

    // Try every possible cut
    for (let i = 1; i < n; i++) {
        // 1. Cut rope into two parts
        let directProduct = i * (n - i);

        // 2. Further divide remaining part
        let recursiveProduct = i * maxProduct(n - i);

        // Store maximum product
        maxValue = Math.max(
            maxValue,
            Math.max(directProduct, recursiveProduct));
    }

    return maxValue;
}

// Driver Code
let n = 10;
console.log("Maximum Product is " + maxProduct(n));

Output
Maximum Product is 36

Consider the following example: Recursion tree for a rope of length 5. 

maxproduct_4
Explanation using recursive tree(same colored states showing overlapping sub-problems)

[Better Approach] Using Dynamic Programming - O(n ^ 2) Time and O(n) Space

The recursive solution repeatedly solves the same rope lengths again and again, such as finding the maximum product for smaller lengths multiple times. To avoid these repeated calculations, we use Dynamic Programming and store the answer for every rope length in a DP array. We build the solution from smaller lengths to larger lengths, where dp[i] stores the maximum product obtainable for a rope of length i. For every length, we try all possible cuts and use previously computed DP values to efficiently find the maximum product.

Consider the following dry run for better understanding: n = 5

  • For len = 2 :
    i = 1 --> directProduct = 1 * 1 = 1, recursiveProduct = 1 * dp[1] = 0
    dp[2] = max(1, 0) = 1
  • For len = 3 :
    i = 1 --> directProduct = 1 * 2 = 2, recursiveProduct = 1 * dp[2] = 1 ---> max(2, 1) = 2
    i = 2 --> directProduct = 2 * 1 = 2, recursiveProduct = 2 * dp[1] = 0 ---> max(2, 0) = 2
    dp[3] = max(2, 2) = 2
  • For len = 4 :
    i = 1 --> directProduct = 1 * 3 = 3, recursiveProduct = 1 * dp[3] = 2 ---> max(3, 2) = 3
    i = 2 --> directProduct = 2 * 2 = 4, recursiveProduct = 2 * dp[2] = 2 ---> max(4, 2) = 4
    i = 3 --> directProduct = 3 * 1 = 3, recursiveProduct = 3 * dp[1] = 0 ---> max(3, 0) = 3
    dp[4] = max(3, 4, 3) = 4
  • For len = 5 :
    i = 1 --> directProduct = 1 * 4 = 4, recursiveProduct = 1 * dp[4] = 4 ---> max(4, 4) = 4
    i = 2 --> directProduct = 2 * 3 = 6, recursiveProduct = 2 * dp[3] = 4 ---> max(6, 4) = 6
    i = 3 --> directProduct = 3 * 2 = 6, recursiveProduct = 3 * dp[2] = 3 ---> max(6, 3) = 6
    i = 4 --> directProduct = 4 * 1 = 4, recursiveProduct = 4 * dp[1] = 0 ---> max(4, 0) = 4
    dp[5] = max(4, 6, 6, 4) = 6

Final answer = dp[5] = 6

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

int maxProduct(int n)
{
    // Base Case
    if (n == 0 || n == 1)
    {
        return 0;
    }

    // DP array where
    // dp[i] stores maximum product
    // obtainable from rope length i
    vector<int> dp(n + 1, 0);

    // Build DP table from bottom up
    for (int len = 2; len <= n; len++)
    {
        // Store maximum product
        int maxValue = 0;

        // Try every possible cut
        for (int i = 1; i < len; i++)
        {
            // 1. Cut rope into two parts
            int directProduct = i * (len - i);

            // 2. Further divide remaining part
            int recursiveProduct = i * dp[len - i];

            // Store maximum product
            maxValue = max(maxValue, max(directProduct, recursiveProduct));
        }

        // Store answer for current length
        dp[len] = maxValue;
    }

    return dp[n];
}

// Driver Code
int main()
{
    int n = 10;
    cout << "Maximum Product is " << maxProduct(n);

    return 0;
}
C
#include <stdio.h>

// Utility function to return maximum
int max(int a, int b)
{
    return (a > b) ? a : b;
}

int maxProduct(int n)
{
    // Base Case
    if (n == 0 || n == 1)
    {
        return 0;
    }

    // DP array where
    // dp[i] stores maximum product
    // obtainable from rope length i
    int dp[n + 1];

    // Initialize DP array
    for (int i = 0; i <= n; i++)
    {
        dp[i] = 0;
    }

    // Build DP table from bottom up
    for (int len = 2; len <= n; len++)
    {
        // Store maximum product
        int maxValue = 0;

        // Try every possible cut
        for (int i = 1; i < len; i++)
        {
            // 1. Cut rope into two parts
            int directProduct = i * (len - i);

            // 2. Further divide remaining part
            int recursiveProduct = i * dp[len - i];

            // Store maximum product
            maxValue = max(maxValue, max(directProduct, recursiveProduct));
        }

        // Store answer for current length
        dp[len] = maxValue;
    }

    return dp[n];
}

// Driver Code
int main()
{
    int n = 10;
    printf("Maximum Product is %d", maxProduct(n));

    return 0;
}
Java
class GFG {
    static int maxProduct(int n)
    {
        // Base Case
        if (n == 0 || n == 1) {
            return 0;
        }

        // DP array where
        // dp[i] stores maximum product
        // obtainable from rope length i
        int[] dp = new int[n + 1];

        // Build DP table from bottom up
        for (int len = 2; len <= n; len++) {
            // Store maximum product
            int maxValue = 0;

            // Try every possible cut
            for (int i = 1; i < len; i++) {
                // 1. Cut rope into two parts
                int directProduct = i * (len - i);

                // 2. Further divide remaining part
                int recursiveProduct = i * dp[len - i];

                // Store maximum product
                maxValue = Math.max(
                    maxValue, Math.max(directProduct,
                                       recursiveProduct));
            }

            // Store answer for current length
            dp[len] = maxValue;
        }

        return dp[n];
    }

    // Driver Code
    public static void main(String[] args)
    {
        int n = 10;
        System.out.println("Maximum Product is "
                           + maxProduct(n));
    }
}
Python
def maxProduct(n):

    # Base Case
    if n == 0 or n == 1:
        return 0

    # DP array where
    # dp[i] stores maximum product
    # obtainable from rope length i
    dp = [0] * (n + 1)

    # Build DP table from bottom up
    for length in range(2, n + 1):

        # Store maximum product
        maxValue = 0

        # Try every possible cut
        for i in range(1, length):

            # 1. Cut rope into two parts
            directProduct = i * (length - i)

            # 2. Further divide remaining part
            recursiveProduct = i * dp[length - i]

            # Store maximum product
            maxValue = max(
                maxValue,
                max(directProduct,
                    recursiveProduct)
            )

        # Store answer for current length
        dp[length] = maxValue

    return dp[n]


# Driver Code
if __name__ == "__main__":
    n = 10
    print("Maximum Product is",
          maxProduct(n))
C#
using System;

class GFG {
    static int maxProduct(int n)
    {
        // Base Case
        if (n == 0 || n == 1) {
            return 0;
        }

        // DP array where
        // dp[i] stores maximum product
        // obtainable from rope length i
        int[] dp = new int[n + 1];

        // Build DP table from bottom up
        for (int len = 2; len <= n; len++) {
            // Store maximum product
            int maxValue = 0;

            // Try every possible cut
            for (int i = 1; i < len; i++) {
                // 1. Cut rope into two parts
                int directProduct = i * (len - i);

                // 2. Further divide remaining part
                int recursiveProduct = i * dp[len - i];

                // Store maximum product
                maxValue = Math.Max(
                    maxValue, Math.Max(directProduct,
                                       recursiveProduct));
            }

            // Store answer for current length
            dp[len] = maxValue;
        }

        return dp[n];
    }

    // Driver Code
    static void Main()
    {
        int n = 10;
        Console.WriteLine("Maximum Product is "
                          + maxProduct(n));
    }
}
JavaScript
function maxProduct(n)
{
    // Base Case
    if (n === 0 || n === 1) {
        return 0;
    }

    // DP array where
    // dp[i] stores maximum product
    // obtainable from rope length i
    let dp = new Array(n + 1).fill(0);

    // Build DP table from bottom up
    for (let len = 2; len <= n; len++) {
        // Store maximum product
        let maxValue = 0;

        // Try every possible cut
        for (let i = 1; i < len; i++) {
            // 1. Cut rope into two parts
            let directProduct = i * (len - i);

            // 2. Further divide remaining part
            let recursiveProduct = i * dp[len - i];

            // Store maximum product
            maxValue = Math.max(
                maxValue,
                Math.max(directProduct, recursiveProduct));
        }

        // Store answer for current length
        dp[len] = maxValue;
    }

    return dp[n];
}

// Driver Code
let n = 10;
console.log("Maximum Product is " + maxProduct(n));

Output
Maximum Product is 36

[Optimal Approach] Using Mathematical Greedy Approach - O(n) Time and O(1) Space

Instead of trying all possible cuts using recursion or DP, this method uses an important mathematical observation: To get the maximum product, we should cut the rope into as many parts of 3 as possible.

  • If we see some examples of this problems, we can easily observe following pattern.
  • The maximum product can be obtained be repeatedly cutting parts of size 3 while size is greater than 4, keeping the last part as size of 2 or 3 or 4.
  • For n = 10, the maximum product is obtained by 3, 3, 4.
  • For n = 11, the maximum product is obtained by 3, 3, 3, 2.

Why does this work?

  • If we cut of length x into a + b, the product becomes a x b. We should cut only if a×b > x otherwise cutting reduces the product.
  • If we take values of x less than 4, we can notice, we never need to cut. For example 3 = 2 + 1, but 2 x 1 < 3
  • For 4, we get max same values 2x2 = 4.
  • Let us now consider x >= 5, let us consider two choices make a cut of length 2 and 3 and compare the two choices 2(x-2) and 3(x-3). If we compute 3(x - 3) - 2(x-2), get x - 5 which is greater than or equal to 0 (never negative). So cutting into a piece of 3 is always better.
  • Now the question arises about larger cuts. We can show that any length larger than 5 needs to be cut for more product. Why? because 3(x - 3) > x for x >= 4.5.
C++
#include <iostream>
using namespace std;

int maxProduct(int n)
{
    // Base Cases
    // Rope of length 2 or 3
    // must be cut at least once
    if (n == 2 || n == 3)
    {
        return n - 1;
    }

    // Store final product
    int product = 1;

    // Keep cutting parts of length 3
    // while remaining length is greater than 4
    while (n > 4)
    {
        // Multiply current product by 3
        product *= 3;

        // Reduce rope length
        n -= 3;
    }

    // Multiply remaining rope length
    return product * n;
}

// Driver Code
int main()
{
    int n = 10;
    cout << "Maximum Product is " << maxProduct(n);

    return 0;
}
C
#include <stdio.h>

// Function to calculate maximum product
int maxProduct(int n)
{
    // Base Cases
    // Rope of length 2 or 3
    // must be cut at least once
    if (n == 2 || n == 3)
    {
        return n - 1;
    }

    // Store final product
    int product = 1;

    // Keep cutting parts of length 3
    // while remaining length is greater than 4
    while (n > 4)
    {
        // Multiply current product by 3
        product *= 3;

        // Reduce rope length
        n -= 3;
    }

    // Multiply remaining rope length
    return product * n;
}

// Driver Code
int main()
{
    int n = 10;
    printf("Maximum Product is %d", maxProduct(n));

    return 0;
}
Java
public class GFG {

    public static int maxProduct(int n)
    {
        // Base Cases
        // Rope of length 2 or 3
        // must be cut at least once
        if (n == 2 || n == 3) {
            return n - 1;
        }

        // Store final product
        int product = 1;

        // Keep cutting parts of length 3
        // while remaining length is greater than 4
        while (n > 4) {
            // Multiply current product by 3
            product *= 3;

            // Reduce rope length
            n -= 3;
        }

        // Multiply remaining rope length
        return product * n;
    }

    // Driver Code
    public static void main(String[] args)
    {
        int n = 10;
        System.out.println("Maximum Product is "
                           + maxProduct(n));
    }
}
Python
def maxProduct(n):
    # Base Cases
    # Rope of length 2 or 3
    # must be cut at least once
    if n == 2 or n == 3:
        return n - 1

    # Store final product
    product = 1

    # Keep cutting parts of length 3
    # while remaining length is greater than 4
    while n > 4:
        # Multiply current product by 3
        product *= 3

        # Reduce rope length
        n -= 3

    # Multiply remaining rope length
    return product * n


# Driver Code
if __name__ == "__main__":
    n = 10
    print("Maximum Product is", maxProduct(n))
C#
using System;

class GFG {
    static int maxProduct(int n)
    {
        // Base Cases
        // Rope of length 2 or 3
        // must be cut at least once
        if (n == 2 || n == 3) {
            return n - 1;
        }

        // Store final product
        int product = 1;

        // Keep cutting parts of length 3
        // while remaining length is greater than 4
        while (n > 4) {
            // Multiply current product by 3
            product *= 3;

            // Reduce rope length
            n -= 3;
        }

        // Multiply remaining rope length
        return product * n;
    }

    // Driver Code
    static void Main()
    {
        int n = 10;
        Console.WriteLine("Maximum Product is "
                          + maxProduct(n));
    }
}
JavaScript
function maxProduct(n)
{
    // Base Cases
    // Rope of length 2 or 3
    // must be cut at least once
    if (n === 2 || n === 3) {
        return n - 1;
    }

    // Store final product
    let product = 1;

    // Keep cutting parts of length 3
    // while remaining length is greater than 4
    while (n > 4) {
        // Multiply current product by 3
        product *= 3;

        // Reduce rope length
        n -= 3;
    }

    // Multiply remaining rope length
    return product * n;
}

// Driver Code
let n = 10;
console.log("Maximum Product is " + maxProduct(n));

Output
Maximum Product is 36

[Optimal Approach] Using Exponentiation - O(log n) Time and O(1) Space

In the above solution, instead of repeatedly subtracting 3 from n and multiplying the result by 3 in a loop, we observe that the number of times we can take 3 is simply n / 3. Therefore, the repeated multiplication of 3 can be represented as exponentiation 3^(n/3), which eliminates the need for iteration.

  • If n is 2 or 3, directly return n - 1 as it is the best possible split.
  • Compute how many full 3s can be taken from n using integer division:
    count3 = n / 3, and find the remainder: rem = n % 3.
  • If rem is 0 --> only 3s are used
  • If rem is 2 --> multiply final result by 2
  • If rem is 1 --> adjust by converting one 3 + 1 into 2 + 2 for optimal product
  • Multiply the result by 3 repeatedly count3 times to account for all 3-partitions.
  • Multiply the final result by rem (if it is 2 or 4), and return the product as the answer.
C++
#include <bits/stdc++.h>
using namespace std;

int maxProduct(int n)
{
    // Edge case: for small values
    if (n == 2 || n == 3)
        return n - 1;

    // Count how many 3s we can take
    int count3 = n / 3;
    int rem = n % 3;

    // If remainder is 1, adjust (3 + 1 -> 2 + 2)
    if (rem == 1)
    {
        count3 -= 1;
        rem += 3; // becomes 4
    }

    // Final product
    int product = 1;

    // multiply all 3s
    for (int i = 0; i < count3; i++)
        product *= 3;

    // handle remaining part (0, 2 or 4)
    if (rem == 2 || rem == 4)
        product *= rem;

    return product;
}

int main()
{
    int n = 10;
    cout << "Maximum Product is " << maxProduct(n);
    return 0;
}
C
#include <stdio.h>

int maxProduct(int n)
{
    // Edge case: for small values
    if (n == 2 || n == 3)
        return n - 1;

    // Count how many 3s we can take
    int count3 = n / 3;
    int rem = n % 3;

    // If remainder is 1, adjust (3 + 1 -> 2 + 2)
    if (rem == 1)
    {
        count3 -= 1;
        rem += 3; // becomes 4
    }

    // Final product
    int product = 1;

    // multiply all 3s
    for (int i = 0; i < count3; i++)
        product *= 3;

    // handle remaining part (0, 2 or 4)
    if (rem == 2 || rem == 4)
        product *= rem;

    return product;
}

int main()
{
    int n = 10;
    printf("Maximum Product is %d", maxProduct(n));
    return 0;
}
Java
public class GFG {

    static int maxProduct(int n)
    {
        // Edge case: for small values
        if (n == 2 || n == 3)
            return n - 1;

        // Count how many 3s we can take
        int count3 = n / 3;
        int rem = n % 3;

        // If remainder is 1, adjust (3 + 1 -> 2 + 2)
        if (rem == 1) {
            count3 -= 1;
            rem += 3; // becomes 4
        }

        // Final product
        int product = 1;

        // multiply all 3s
        for (int i = 0; i < count3; i++)
            product *= 3;

        // handle remaining part (0, 2 or 4)
        if (rem == 2 || rem == 4)
            product *= rem;

        return product;
    }

    public static void main(String[] args)
    {
        int n = 10;
        System.out.println("Maximum Product is "
                           + maxProduct(n));
    }
}
Python
def maxProduct(n):
    # Edge case: for small values
    if n == 2 or n == 3:
        return n - 1

    # Count how many 3s we can take
    count3 = n // 3
    rem = n % 3

    # If remainder is 1, adjust (3 + 1 -> 2 + 2)
    if rem == 1:
        count3 -= 1
        rem += 3  # becomes 4

    # Final product
    product = 1

    # multiply all 3s
    for _ in range(count3):
        product *= 3

    # handle remaining part (0, 2 or 4)
    if rem == 2 or rem == 4:
        product *= rem

    return product


# Driver Code
if __name__ == "__main__":
    n = 10
    print("Maximum Product is", maxProduct(n))
C#
using System;

class GFG {
    static int maxProduct(int n)
    {
        // Edge case: for small values
        if (n == 2 || n == 3)
            return n - 1;

        // Count how many 3s we can take
        int count3 = n / 3;
        int rem = n % 3;

        // If remainder is 1, adjust (3 + 1 -> 2 + 2)
        if (rem == 1) {
            count3 -= 1;
            rem += 3; // becomes 4
        }

        // Final product
        int product = 1;

        // multiply all 3s
        for (int i = 0; i < count3; i++)
            product *= 3;

        // handle remaining part (0, 2 or 4)
        if (rem == 2 || rem == 4)
            product *= rem;

        return product;
    }

    static void Main()
    {
        int n = 10;
        Console.WriteLine("Maximum Product is "
                          + maxProduct(n));
    }
}
JavaScript
function maxProduct(n)
{
    // Edge case: for small values
    if (n === 2 || n === 3)
        return n - 1;

    // Count how many 3s we can take
    let count3 = Math.floor(n / 3);
    let rem = n % 3;

    // If remainder is 1, adjust (3 + 1 -> 2 + 2)
    if (rem === 1) {
        count3 -= 1;
        rem += 3; // becomes 4
    }

    // Final product
    let product = 1;

    // multiply all 3s
    for (let i = 0; i < count3; i++)
        product *= 3;

    // handle remaining part (0, 2 or 4)
    if (rem === 2 || rem === 4)
        product *= rem;

    return product;
}

// Driver Code
let n = 10;
console.log("Maximum Product is " + maxProduct(n));

Output
Maximum Product is 36
Comment