Chapter 15 solutions - Dynamic Programming


From pseudo-code to python

Recursive top-down implementation

p = [0, 1, 5, 8, 9, 10, 17, 17, 20, 24, 30]

def cut_rod(p, n):
    if n == 0:
        return 0
    q = p[0]
    for i in range(1, n+1):
        q = max(q, p[i] + cut_rod(p, n-i))
    return q


res = cut_rod(p, 4)
print(res)

Memoized cut rod

def memoized_cut_rod(p, n):
    r = [-1 for _ in range(n + 1)]

    return memoized_cut_rod_aux(p, n, r)


def memoized_cut_rod_aux(p, n, r):
    if r[n] >= 0:
        return r[n]
    q = p[0]
    if n == 0:
        q = 0
    else:
        for i in range(1, n + 1):
            q = max(q, p[i] + memoized_cut_rod_aux(p, n - i, r))

    r[n] = q
    return q

res = memoized_cut_rod(p, 4)
print(res)

Bottom up cut rod

def bottom_up_cut_rod(p, n):
    r = [0 for _ in range(n + 1)]

    for j in range(1, n + 1):
        q = p[0]
        for i in range(1, j + 1):
            q = max(q, p[i] + r[j - i])
        r[j] = q

    return r[n]

res = bottom_up_cut_rod(p, 4)
print(res)

15.1-1

Show that equation (15.4) follows from equation (15.3) and the initial condition .

Binomial of one variable refer here counts the number of calls (including recursive calls) due to the call CUT-ROD. It also means how many ways we can cut the rod.

Let so we can get

Now we want to run how many ways to cut the rod from until . This recursion tree has

incase I forgot, the sum of power of 2 is a geometric series

15.1-2

Show, by means of a counterexample, that the following “greedy” strategy does not always determine an optimal way to cut rods. Define the density of a rod of length to be , that is, its value per inch. The greedy strategy for a rod of length cuts off a first piece of length , where , having maximum density. It then continues by applying the greedy strategy to the remaining piece of length .

15.1-3

Consider a modification of the rod-cutting problem in which, in addition to a price for each rod, each cut incurs a fixed cost of . The revenue associated with a solution is now the sum of the prices of the pieces minus the costs of making the cuts. Give a dynamic-programming algorithm to solve this modified problem.

def bottom_up_cut_rod(p, n, c):
    r = [0 for _ in range(n + 1)]

    for j in range(1, n + 1):
        q = p[0]
        for i in range(1, j + 1):
            q = max(q, p[i] + r[j - i] - c)
        r[j] = q

    return r[n]

res = bottom_up_cut_rod(p, 4, 0.5)
print(res)

15.1-4

Modify MEMOIZED-CUT-ROD to return not only the value but the actual solution, too.

15.1-5

The Fibonacci numbers are defined by recurrence (3.22). Give an -time dynamic programming algorithm to compute the th Fibonacci number. Draw the subproblem graph. How many vertices and edges are in the graph?

def fibonacci_dynamic(n):
    a, b = 0, 1
    while n > 0:
        a, b = b, a + b
        n -= 1
    return a

res = fibonacci_dynamic(8)
print(res)