Implement a Dynamic Programming Solution for the Rod Cutting Problem

problem-solving
Published

December 14, 2024

The Rod Cutting Problem is a classic example perfectly suited to illustrate the power of dynamic programming. This optimization problem involves determining the maximum revenue obtainable by cutting a rod of a given length into smaller pieces and selling them. Each piece has an associated price, which may vary depending on its length. A brute-force approach would be computationally expensive, especially for longer rods, making dynamic programming a far more efficient solution.

Understanding the Problem

Imagine you have a rod of length n. You can cut this rod into smaller pieces of lengths 1, 2, 3, ..., n. Each length i has a corresponding price price[i]. The goal is to find the optimal way to cut the rod to maximize your total revenue.

For instance, if you have a rod of length 4 and the following prices:

  • price[1] = 1
  • price[2] = 5
  • price[3] = 8
  • price[4] = 9

The optimal solution would be to not cut the rod at all (selling it as a length 4 piece) for a total revenue of 9. Other potential cuts (e.g., cutting it into two pieces of length 2) would yield less revenue.

Dynamic Programming Approach

Dynamic programming solves this problem by breaking it down into smaller overlapping subproblems. Instead of repeatedly calculating the revenue for the same subproblems, it stores the results in a table (often an array) and reuses them as needed. This reduces computation time.

Here’s a Python implementation using a bottom-up dynamic programming approach:

def rod_cutting(prices, n):
    """
    Solves the rod cutting problem using dynamic programming.

    Args:
        prices: A list of prices, where prices[i] is the price of a rod of length i+1.
        n: The length of the rod.

    Returns:
        The maximum revenue obtainable.
    """

    # Create a DP table to store maximum revenue for different rod lengths
    dp = [0] * (n + 1)

    # Iterate through all possible rod lengths
    for i in range(1, n + 1):
        # Iterate through all possible cuts for the current rod length
        for j in range(1, i + 1):
            dp[i] = max(dp[i], prices[j - 1] + dp[i - j])

    return dp[n]


# Example usage:
prices = [1, 5, 8, 9, 10, 17, 17, 20, 24, 30]  # prices[i] is the price of a rod of length i+1
n = 4
max_revenue = rod_cutting(prices, n)
print(f"Maximum revenue for a rod of length {n}: {max_revenue}")  # Output: 10

n = 10
max_revenue = rod_cutting(prices, n)
print(f"Maximum revenue for a rod of length {n}: {max_revenue}") # Output: 30

This code first initializes a DP table dp with zeros. Then, it iteratively calculates the maximum revenue for each rod length from 1 to n. For each length i, it considers all possible cuts (j) and updates dp[i] with the maximum revenue obtained so far. Finally, dp[n] contains the maximum revenue for the entire rod of length n.

Time and Space Complexity

The dynamic programming solution has a time complexity of O(n^2) and a space complexity of O(n), where n is the length of the rod. This is a significant improvement over the exponential time complexity of a brute-force approach. The space complexity can be further optimized to O(1) if we only need the final maximum revenue and not the complete DP table.