# Dynamic Programming - Rod Cutting

## Introduction

Dynamic programming is well known algorithm design method. It is used to solve problems where problem of size N is solved using solution of problems of size N - 1 (or smaller). Introductory example is calculation of Fibonacci numbers where F(N) (problem of size N) is calculated as sum of F(N - 2) and F(N - 1) (problems of size N - 2 and N - 1). Usually smaller problems are calculated many times. To avoid repeatable calculations their result is memorized in an array. This technique (known as memoization) significantly speeds up calculations. In the next sections I will present classic problem known as rod cutting which is solved using dynamic programming.

## Problem

Rod cutting problem is formulated as maximum profit that can be obtained by cutting a rod into parts. The question is how to cut the rod so that profit is maximized.

## Recursive Algorithm

```
func max(a : int, b : int) -> int
{
a > b ? a : b
}
```

As rod cutting problem mentions maximum profit, likely maximum function is needed. The above code snippet presents such function.

```
func cutrod(price[_] : int, len : int) -> int
{
var i = 0;
var max_p = -1;
if (len <= 0)
{
max_p = 0
}
else
{
while (i < len)
{
max_p = max(max_p, price[i] + cutrod(price, len - i - 1));
i = i + 1
}
};
max_p
}
```

Now a little more difficult part. Given price list (in array `price`

)
of different rod lengths and length of the rod, maximum profit `max_p`

can
be calculated as profit obtained by cutting rod of length `i`

plus profit earned by
cutting rod of `length - i`

(in the code above `1`

is subtracted as
rod of length `i`

is at index `i - 1`

in the array `price`

). Please note
that problem of size `len`

is calculated using solution to problem
of size `len - i - 1`

. This sentence can be formulated by simple
expression `max_p = max(max_p, price[i] + cutrod(price, len - i - 1))`

.

```
func main() -> int
{
let price = [ 1, 5, 8, 9, 10, 17, 17, 20 ] : int;
cutrod(price, 8)
}
```

An example of maximizing profit obtained by cutting a rod of length 8 where sections of lengths 1, 2, 3, ... can be sold for 1, 5, 8, ... is presented above.

### Memoization

```
func cutrod(price[P] : int, memo[M] : int, len : int) -> int
{
var i = 0;
var max_p = -1;
if (memo[len] != -1)
{
max_p = memo[len]
}
else
{
while (i < len)
{
max_p = max(max_p, price[i] + cutrod(price, memo, len - i - 1));
i = i + 1
}
};
memo[len] = max_p
}
```

```
func main() -> int
{
let price = [ 1, 5, 8, 9, 10, 17, 17, 20 ] : int;
let memo = [ 0, -1, -1, -1, -1, -1, -1, -1, -1 ] : int;
cutrod(price, memo, 8)
}
```

As mentioned in the introduction dynamic programming uses memoization to speed up
calculations. Solutions to smaller problems are stored in array `memo`

.
When function `cutrod`

is invoked for given rod length and profit of
selling such rod is known then it is returned immediately. The above code snippet
introduces this optimization.

## Summary

This article presents short introduction to dynamic programming. There are many other classic problems which can be solved using this method. Coin change, matrix multiplication or longest common subsequence are examples of most well known problems. I encourage you to study them.