792-rod-cutting-dp — Rod Cutting Problem
Tutorial Video
Text description (accessibility)
This video demonstrates the "792-rod-cutting-dp — Rod Cutting Problem" functional Rust example. Difficulty level: Advanced. Key concepts covered: Functional Programming. Rod cutting is a classic unbounded knapsack variant: given a rod of length n and prices for each length, maximize revenue by cutting the rod into pieces. Key difference from OCaml: 1. **Recurrence**: Identical to coin change but indexed from 1 (rod lengths) instead of the coin denominations; the algorithms are structurally the same.
Tutorial
The Problem
Rod cutting is a classic unbounded knapsack variant: given a rod of length n and prices for each length, maximize revenue by cutting the rod into pieces. Unlike 0/1 knapsack, pieces of the same length can be used multiple times. It was popularized by Cormen et al. "Introduction to Algorithms" and models real cutting-stock problems in manufacturing, timber processing, and cable management.
🎯 Learning Outcomes
dp[i] = max revenue for rod of length iCode Example
#![allow(clippy::all)]
//! # Rod Cutting Problem
pub fn rod_cutting(prices: &[usize], n: usize) -> usize {
let mut dp = vec![0; n + 1];
for i in 1..=n {
for j in 1..=i.min(prices.len()) {
dp[i] = dp[i].max(prices[j - 1] + dp[i - j]);
}
}
dp[n]
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_rod() {
assert_eq!(rod_cutting(&[1, 5, 8, 9, 10, 17, 17, 20], 8), 22);
}
#[test]
fn test_small() {
assert_eq!(rod_cutting(&[1, 5, 8, 9], 4), 10);
}
}Key Differences
cut array; Rust's Option<usize> per cell is cleaner than OCaml's -1 sentinel.None (unsaleable lengths); handling this requires wrapping prices in Option.OCaml Approach
OCaml implements the same recurrence with Array.make (n+1) 0 and nested for loops. The reconstruction uses a cut: int array tracking which cut was made at each length. Functional style can use Array.fold_left over cut lengths. OCaml's List.init generates the price list naturally. The rod cutting problem is typically presented alongside the coin change problem in OCaml algorithm courses.
Full Source
#![allow(clippy::all)]
//! # Rod Cutting Problem
pub fn rod_cutting(prices: &[usize], n: usize) -> usize {
let mut dp = vec![0; n + 1];
for i in 1..=n {
for j in 1..=i.min(prices.len()) {
dp[i] = dp[i].max(prices[j - 1] + dp[i - j]);
}
}
dp[n]
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_rod() {
assert_eq!(rod_cutting(&[1, 5, 8, 9, 10, 17, 17, 20], 8), 22);
}
#[test]
fn test_small() {
assert_eq!(rod_cutting(&[1, 5, 8, 9], 4), 10);
}
}#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_rod() {
assert_eq!(rod_cutting(&[1, 5, 8, 9, 10, 17, 17, 20], 8), 22);
}
#[test]
fn test_small() {
assert_eq!(rod_cutting(&[1, 5, 8, 9], 4), 10);
}
}
Deep Comparison
OCaml vs Rust: Rod Cutting Dp
Overview
See the example.rs and example.ml files for detailed implementations.
Key Differences
| Aspect | OCaml | Rust |
|---|---|---|
| Type system | Hindley-Milner | Ownership + traits |
| Memory | GC | Zero-cost abstractions |
| Mutability | Explicit ref | mut keyword |
| Error handling | Option/Result | Result<T, E> |
See README.md for detailed comparison.
Exercises
rod_cutting_reconstruct(prices, n) -> Vec<usize> that returns the lengths of cuts made (in any order), not just the max revenue.max_revenue - k * cut_cost, and find the optimal number of cuts.