Dynamic Programming Explained: Concepts & Applications
Dynamic Programming Explained: Concepts & Applications
Dynamic programming
Dynamic programming
• The principle is similar to divide and conquer algorithm
• The problem is divided into many subproblems
• The problem is further divided into subproblems, until the
subproblems can be solved easily
• Combining the solutions of the subproblems gives the solution
of the original problem
2
Dynamic programming
• Difference with divide and conquer algorithm
• Dynamic programming is applied when the subproblems are
not independent
• Common subproblems
• When subproblems are not independent
• Applying divide and conquer algorithm
– Do the same work (solve the same subproblem) multiple times
• Applying dynamic programming algorithm
– Each subproblem is solved once and the result is saved to an array,
then if the subproblem is encountered again, only the result is
reused
– Reduce complexity
3
Dynamic programming
• Dynamic programming = Divide and conquer + Memory
4
Dynamic programming
• Dynamic programming algorithms are often applied to
optimization problems
• These problems can have multiple solutions, we want to find the optimal
solution according to an objective function
5
Some applications
• Binomial expansion (a+b)n
• Matrix chain multiplication
• Longest common subsequence
• Backpacking
6
Binomial expansion (a+b)n
1 k 0, k n
C k 1
k
n 1 1 k n 1
n k
n 1
C C
7
Binomial expansion (a+b)n
• There are many values of C(i, j) with i<k and j < n, which are calculated
many times
• High complexity
8
Binomial expansion (a+b)n
C(3,5) C(4,5)
9
Binomial expansion (a+b)n
c if n 1
C ( n)
2C (n 1) d else
where c and d are constants
10
Binomial expansion (a+b)n
k 0
n2
2 n 1 1
2 n 1
C (1) d 2 2 k n 1
cd
k 0 2 1
2 n 1 (c d ) d
• So: C(n) = (2n)
11
Binomial expansion (a+b)n
• Dynamic programming algorithm
• Use array C[0..n,0..k] to store intermediate results
• C[i, j] contains the value Ci j
• C[i,j] is calculated
1 j 0 hay j i
C[i, j ]
C[i 1, j 1] C[i 1, j ]
• Calculate the values of Pascal's triangle
n/k 0 1 2 3 4 5
0 1
1 1 1
2 1 2 1
3 1 3 3 1
4 1 4 6 4 1
5 1 5 10 10 5 1
12
Binomial expansion (a+b)n
13
Binomial expansion (a+b)n
n/k 0 1 2 3 4 5 n/k 0 1 2 3 4 5
0 1 0 1
1 1 1 1 1 1
2 1 1 2 1 2 1
3 1 1 3 1 3 3 1
4 1 4 4 6 4 1
5 1 5 10 10 5 1
6 6 20 15 6
7 7 35 21
8 8 56
Initialize column 0 and diagonal Calculate by column
15
Binomial expansion (a+b)n
• Dynamic programming algorithm
C2(k, n)
begin
// use one-dimensional array C[0..n]
C[0] = 1 // initialize row 1
C[1] = 1
// calculate each row
Use only one- for i from 2 to n do
dimensional array p1 = 1
to store current for j from 1 to i-1 do
line of Pascal's p2 = C[j]
triangle C[j] = p1 + p2
p1 = p2
endfor
C[i] = 1 // element on the diagonal
endfor
return (C[k])
end
16
Binomial expansion (a+b)n
17
Binomial expansion (a+b)n
18
Dynamic programming algorithm design
• Identification
• Build a divide and conquer algorithm/simple algorithm
• Complexity assessment (exponential)
• The same subproblem is solved multiple times
• Build
• Extract the ”conquer" part of the divide and conquer algorithm and replace
the recursive calls with searching for values in an array
• Instead of returning the value, save the value to the array
• Use the divide and conquer algorithm's stopping condition to initialize the
array values
• Find a way to calculate the values of array
• Build a loop to calculate the values of array
19
Dynamic programming algorithm design
21
Matrix chain multiplication
• Example
• Matrix multiplication
M1(10x20).M2(20x50).M3(50x1).M4(1x100)
22
Matrix chain multiplication
• Brute Force Algorithm (1)
• Try all possible combinations
• Calculate the number of multiplications for each method
• Choose the best way
23
Matrix chain multiplication
P ( n) ( 2 n )
24
Matrix chain multiplication
27
Matrix chain multiplication
chainMatrixRecur(1,4)
(2.2) (3,4) (2,3) (4.4) (1,1) (2.2) (3.3) (4.4) (1,1) (2,3) (1,2) (3.3)
28
Matrix chain multiplication
• So, to calculate mi,j we must have the values mi,k and mk+1,j with ik<j
29
Matrix chain multiplication
0 i j
i mi , j
min (mi ,k mk 1, j d i 1d k d j ) i j
ik j
m[i,k]
j
30
Matrix chain multiplication
31
Matrix chain chain multiplication
• Build diagonal s = 1
– m[1,2] = min(m[1,k] + m[k+1,2] + d 0 d 1 d 2 ), with 1 k<2
= min(m[1,1] + m[2,2] + d 0 d 1 d 2 )
= d 0 d 1 d 2 = 10x20x50 = 10000
g[1,2] = k = 1
– m[2,3] = min(m[2,k] + m[k+1,3] + d 1 d 2 d 3 ), with 2 k<3
= d 1 d 2 d 3 = 20x50x1 = 1000
g[2,3] = k = 2
– m[3,4] = d 2 d 3 d 4 = 50x1x100 = 5000
g[3,4] = k = 3
33
Matrix multiplication
34
Matrix multiplication
35
Matrix chain multiplication
s=0
36
Matrix chain multiplication
37
Matrix chain multiplication
38
Matrix chain multiplication
chainMatrixProduct(M, g, i, j)
// array of matrices
begin
if (i < j) then
X = chainMatrixProduct(M, g, i, g[i,j])
Y = chainMatrixProduct(M, g, g[i,j]+1,j)
return (matrixProduct(X,Y))
else // i = j
return (Mi)
endif
end
• chainMatrixProduct(M, g, 1, 4) will calculate the product M1.M2.M3.M4 in the order:
((M1.(M2.M3)).M4)
• Because: g[1,4] = 3, g[1,3] = 1
39
Matrix chain multiplication
40
Longest common subsequence
• Problem
• Given two sequences of symbols X and Y, the longest common subsequence
(LCS) of X and Y is the sequence of symbols obtained from X by deleting
some elements and also obtained from Y by deleting some elements
41
Longest common subsequence
• Brute force algorithm
• Suppose X=x1x2…xn and Y = y1y2…ym
• Compare each subsequence of X with the sequence of Y
• There are 2n subsequences of X
• Comparing each subsequence of X with Y will perform m comparisons
• The complexity will be O(m2n)
• Exponential function!
42
Longest common subsequence
43
Longest common subsequence
44
Longest common subsequence
LCS-length(i,j)
begin
if (i = 0 or j = 0) then
return (0)
else
if (xi = yj) then
return (LCS-length(i-1,j-1) + 1)
else
return (max(LCS-length(i-1, j), LCS-length(i, j-1)))
endif
endif
end
45
Longest common subsequence
46
Longest common subsequence
2 B
3 C
4 B
X=ABCB, Y=BDCAB
48
Longest common subsequence
2 B 0
3 C 0
4 B 0
for i from 0 to n do c[i,0]=0
for j from 0 to m do c[0,j]=0 49
Longest common subsequence
2 B 0
3 C 0
4 B 0
if (xi = yj) then c[i,j] = c[i-1,j-1] + 1
else c[i,j] = max(c[i-1,j], c[i,j-1])
50
Longest common subsequence
2 B 0
3 C 0
4 B 0
if (xi = yj) then c[i,j] = c[i-1,j-1] + 1
else c[i,j] = max(c[i-1,j], c[i,j-1])
51
Longest common subsequence
2 B 0
3 C 0
4 B 0
if (xi = yj) then c[i,j] = c[i-1,j-1] + 1
else c[i,j] = max(c[i-1,j], c[i,j-1])
52
Longest common subsequence
2 B 0
3 C 0
4 B 0
if (xi = yj) then c[i,j] = c[i-1,j-1] + 1
else c[i,j] = max(c[i-1,j], c[i,j-1])
53
Longest common subsequence
2 B 0 1
3 C 0
4 B 0
if (xi = yj) then c[i,j] = c[i-1,j-1] + 1
else c[i,j] = max(c[i-1,j], c[i,j-1])
54
Longest common subsequence
2 B 0 1 1 1 1
3 C 0
4 B 0
if (xi = yj) then c[i,j] = c[i-1,j-1] + 1
else c[i,j] = max(c[i-1,j], c[i,j-1])
55
Longest common subsequence
2 B 0 1 1 1 1 2
3 C 0
4 B 0
if (xi = yj) then c[i,j] = c[i-1,j-1] + 1
else c[i,j] = max(c[i-1,j], c[i,j-1])
56
Longest common subsequence
2 B 0 1 1 1 1 2
3 C 0 1 1
4 B 0
if (xi = yj) then c[i,j] = c[i-1,j-1] + 1
else c[i,j] = max(c[i-1,j], c[i,j-1])
57
Longest common subsequence
2 B 0 1 1 1 1 2
3 C 0 1 1 2
4 B 0
if (xi = yj) then c[i,j] = c[i-1,j-1] + 1
else c[i,j] = max(c[i-1,j], c[i,j-1])
58
Longest common subsequence
2 B 0 1 1 1 1 2
3 C 0 1 1 2 2 2
4 B 0
if (xi = yj) then c[i,j] = c[i-1,j-1] + 1
else c[i,j] = max(c[i-1,j], c[i,j-1])
59
Longest common subsequence
2 B 0 1 1 1 1 2
3 C 0 1 1 2 2 2
4 B 0 1
if (xi = yj) then c[i,j] = c[i-1,j-1] + 1
else c[i,j] = max(c[i-1,j], c[i,j-1])
60
Longest common subsequence
2 B 0 1 1 1 1 2
3 C 0 1 1 2 2 2
4 B 0 1 1 2 2
if (xi = yj) then c[i,j] = c[i-1,j-1] + 1
else c[i,j] = max(c[i-1,j], c[i,j-1])
61
Longest common subsequence
2 B 0 1 1 1 1 2
3 C 0 1 1 2 2 2
4 B 0 1 1 2 2 3
if (xi = yj) then c[i,j] = c[i-1,j-1] + 1
else c[i,j] = max(c[i-1,j], c[i,j-1])
62
Longest common subsequence
63
Longest common subsequence
64
Longest common subsequence
2 B 0 1 1 1 1 2
3 C 0 1 1 2 2 2
4 B 0 1 1 2 2 3
Longest common subsequence (reverse order): BCB
Longest common subsequence: BCB
65
Longest common subsequence
• Problem
• There is a backpack that can hold at most a weight W. There are n objects, each
object has a weight wi and a value bi
• W, wi and bi are integers
• Put the items in the backpack so that the total value of the backpack is the
largest
• Example
Objects Weight - wi Value - bi
2 8
5 10
3 6
W = 12
Backpack 9 2
4 3
68
Backpacking
• Brute force algorithm
• There are n objects, so there are 2n subsets of objects of the set of n objects
• Iterate through all 2n subsets of objects and select the set with the largest total
value whose total weight is less than W
69
Backpacking
• Divide and conquer algorithm (1)
• The problem can be divided into subproblems
• Instead of considering k objects, consider k-1 objects…
• Let vk,w be the maximum total value of the backpack whose weight does not
exceed w when using only 1…k objects
• For each object k, we need to answer the question:
• Can the current backpack contain object k?
• Answer
• If the current remaining weight w of the backpack is less than wk then the
backpack cannot contain object k
• On the contrary, w wk then two cases occur:
– Don't add object k into the backpack, use only 1…k-1 objects
– Add object k to the backpack, then the value of the backpack increases by bk but the
remaining weight of the backpack decreases by wk (i.e. equal to w-wk)
– The case giving the largest total value of the backpack will be selected
70
Backpacking
vk 1, w if wk w
vk , w
max{vk 1, w , vk 1, w wk bk } else
• Explanation
• If wk > w, it is not possible to add object k to the backpack, only consider
objects 1…k-1 (including k-1 objects)
• If wk w,
– If using only objects 1…k-1 gives the largest total backpack value, then don't use
object k
– Use object k if the total value of the backpack is the largest, then consider
objects 1…k-1 with the remaining weight of the backpack being w-wk
71
Backpacking
0 k 0
vk , w vk 1, w wk w
max(v
k 1, w , vk 1, w wk bk ) wk w
72
Backpacking
backpack (k, w)
begin
if (k = 0) then return 0
else
if (wk > w) then
return backpack(k-1,w) // don't use object k
else
x = backpack(k-1,w)
y = backpack(k-1,w-wk) + bk
return (max(x, y))
endif
endif
end
Use: backpack(n, W)
73
Backpacking
74
Backpacking
75
Backpacking
76
Backpacking
• Example (1)
W = 5 (maximum weight the backpack can hold)
n = 4 (4 objects)
The objects have (weight, value) in order:
(2,3), (3,4), (4,5), (5,6)
78
Backpacking
Example (2)
k 0 1 2 3 4
W
0 0
1 0
2 0
3 0
4 0
5 0
for w = 0 to W do v[0,w] = 0
79
Backpacking
Example (3)
k 0 1 2 3 4
W
0 0 0 0 0 0
1 0
2 0
3 0
4 0
5 0
for k = 0 to n do v[k,0] = 0
80
Backpacking
Example (4)
k 0 1 2 3 4 Objects
W
0 0 0 0 0 0
1: (2,3)
k=1 2: (3,4)
1 0 0
bk= 3 3: (4,5)
2 0
wk =2 4: (5,6)
3 0
4 0 w= 1
5 0 w-wk=-1
if wk <= w then // the object cannot be used
if bk + v[k-1,w-wk ] > v[k-1,w] then
v[k,w] = bk + v[k-1,w-wk ]
else
v[k,w] = v[k-1,w]
else v[k,w] = v[k-1,w] // w k > w, object k is not used 81
Backpacking
Example (5)
k 0 1 2 3 4 Objects
W
0 0 0 0 0 0 1: (2,3)
1 0 0
k=1 2: (3,4)
bk= 3 3: (4,5)
2 0 3
wk =2 4: (5,6)
3 0
4 0 w= 2
5 0 w-wk=0
if wk <= w then // the object cannot be used
if bk + v[k-1,w-wk ] > v[k-1,w] then
v[k,w] = bk + v[k-1,w-wk ]
else
v[k,w] = v[k-1,w]
else v[k,w] = v[k-1,w] // wk > w, object k is not used 82
Backpacking
Example (6)
k 0 1 2 3 4 Objects
W
0 0 0 0 0 0
1: (2,3)
k=1 2: (3,4)
1 0 0
bk= 3 3: (4,5)
2 0 3
wk =2 4: (5,6)
3 0 3
4 0 w= 3
5 0 w-wk =1
if wk <= w then // the object cannot be used
if bk + v[k-1,w-wk ] > v[k-1,w] then
v[k,w] = bk + v[k-1,w-wk ]
else
v[k,w] = v[k-1,w]
else v[k,w] = v[k-1,w] // wk > w, item k is not used 83
Backpacking
Example (7)
k 0 1 2 3 4 Objects
W
0 0 0 0 0 0
1: (2,3)
k=1 2: (3,4)
1 0 0
bk= 3 3: (4,5)
2 0 3
wk =2 4: (5,6)
3 0 3
4 0 3 w= 4
5 0 w-wk =2
if wk <= w then // the object cannot be used
if bk + v[k-1,w-wk ] > v[k-1,w] then
v[k,w] = bk + v[k-1,w-wk ]
else
v[k,w] = v[k-1,w]
else v[k,w] = v[k-1,w] // wk > w, object k is not used 84
Backpacking
Example (8)
k 0 1 2 3 4 Objects
W
0 0 0 0 0 0
1: (2,3)
k=1 2: (3,4)
1 0 0
bk = 3 3: (4,5)
2 0 3
wk =2 4: (5,6)
3 0 3
4 0 3 w= 5
5 0 3 w-wk =2
if wk <= w then // the object cannot be used
if bk + v[k-1,w-wk ] > v[k-1,w] then
v[k,w] = bk + v[k-1,w-wk ]
else
v[k,w] = v[k-1,w]
else v[k,w] = v[k-1,w] // wk > w, object k is not used 85
Backpacking
Example (9)
k 0 1 2 3 4 Objects
W
0 0 0 0 0 0
1: (2,3)
k=2 2: (3,4)
1 0 0 0
bk = 4 3: (4,5)
2 0 3
wk =3 4: (5,6)
3 0 3
4 0 3 w= 1
5 0 3 w-wk=-2
if wk <= w then // the object cannot be used
if bk + v[k-1,w-w k ] > v[k-1,w] then
v[k,w] = bk + v[k-1,w-wk ]
else
v[k,w] = v[k-1,w]
else v[k,w] = v[k-1,w] // w k > w, object k is not used 86
Backpacking
Example (10)
k 0 1 2 3 4 Objects
W
0 0 0 0 0 0
1: (2,3)
k=2 2: (3,4)
1 0 0 0
bk = 4 3: (4,5)
2 0 3 3
wk =3 4: (5,6)
3 0 3
4 0 3 w= 2
5 0 3 w-wk=-1
if wk <= w then // the object cannot be used
if bk + v[k-1,w-w k ] > v[k-1,w] then
v[k,w] = bk + v[k-1,w-wk ]
else
v[k,w] = v[k-1,w]
else v[k,w] = v[k-1,w] // w k > w, object k is not used 87
Backpacking
Example (11)
k 0 1 2 3 4 Objects
W
0 0 0 0 0 0
1: (2,3)
k=2 2: (3,4)
1 0 0 0
bk = 4 3: (4,5)
2 0 3 3
wk =3 4: (5,6)
3 0 3 4
4 0 3 w= 3
5 0 3 w-wk =0
if wk <= w then // the object cannot be used
if bk + v[k-1,w-wk ] > v[k-1,w] then
v[k,w] = b k + v[k-1,w-w k ]
else
v[k,w] = v[k-1,w]
else v[k,w] = v[k-1,w] // wk > w, object k is not used 88
Backpacking
Example (12)
k 0 1 2 3 4 Objects
W
0 0 0 0 0 0
1: (2,3)
k=2 2: (3,4)
1 0 0 0
bk = 4 3: (4,5)
2 0 3 3
wk =3 4: (5,6)
3 0 3 4
4 0 3 4 w= 4
5 0 3 w-wk =1
if wk <= w then // the object cannot be used
if bk + v[k-1,w-wk] > v[k-1,w] then
v[k,w] = bk + v[k-1,w-wk]
else
v[k,w] = v[k-1,w]
else v[k,w] = v[k-1,w] // wk > w, object k is not used 89
Backpacking
Example (13)
k 0 1 2 3 4 Objects
W
0 0 0 0 0 0
1: (2,3)
k=2 2: (3,4)
1 0 0 0
bk = 4 3: (4,5)
2 0 3 3
wk =3 4: (5,6)
3 0 3 4
4 0 3 4 w= 5
5 0 3 7 w-wk =2
if wk <= w then // the object cannot be used
if bk + v[k-1,w-wk ] > v[k-1,w] then
v[k,w] = bk + v[k-1,w-wk ]
else
v[k,w] = v[k-1,w]
else v[k,w] = v[k-1,w] // wk > w, object k is not used 90
Backpacking
Example (14)
k 0 1 2 3 4 Objects
W
0 0 0 0 0 0
1: (2,3)
k=3 2: (3,4)
1 0 0 0 0
bk = 5 3: (4,5)
2 0 3 3 3
wk =4 4: (5,6)
3 0 3 4 4
4 0 3 4 w= 1..3
5 0 3 7 w-wk <0
if wk <= w then // the object cannot be used
if bk + v[k-1,w-wk ] > v[k-1,w] then
v[k,w] = bk + v[k-1,w-wk ]
else
v[k,w] = v[k-1,w]
else v[k,w] = v[k-1,w] // w k > w, item k is not used 91
Backpacking
Example (15)
k 0 1 2 3 4 Objects
W
0 0 0 0 0 0
1: (2,3)
k=3 2: (3,4)
1 0 0 0 0
bk = 5 3: (4,5)
2 0 3 3 3
wk =4 4: (5,6)
3 0 3 4 4
4 0 3 4 5 w= 4
5 0 3 7 w-wk =0
if wk <= w then // the object cannot be used
if bk + v[k-1,w-wk ] > v[k-1,w] then
v[k,w] = bk + v[k-1,w-wk ]
else
v[k,w] = v[k-1,w]
else v[k,w] = v[k-1,w] // wk > w, object k is not used 92
Backpacking
Example (16)
k 0 1 2 3 4 Objects
W
0 0 0 0 0 0
1: (2,3)
k=3 2: (3,4)
1 0 0 0 0
bk = 5 3: (4,5)
2 0 3 3 3
wk=4 4: (5,6)
3 0 3 4 4
4 0 3 4 5 w= 5
5 0 3 7 7 w-wk =1
if wk <= w then // the object cannot be used
if bk + v[k-1,w-wk ] > v[k-1,w] then
v[k,w] = bk + v[k-1,w-wk ]
else
v[k,w] = v[k-1,w]
else v[k,w] = v[k-1,w] // wk > w, object k is not used 93
Backpacking
Example (17)
k 0 1 2 3 4 Objects
W
0 0 0 0 0 0
1: (2,3)
k=4 2: (3,4)
1 0 0 0 0 0
bk = 6 3: (4,5)
2 0 3 3 3 3
wk =5 4: (5,6)
3 0 3 4 4 4
4 0 3 4 5 5 w= 1..4
5 0 3 7 7 w-wk < 0
if wk <= w then // the object cannot be used
if bk + v[k-1,w-wk ] > v[k-1,w] then
v[k,w] = bk + v[k-1,w-wk ]
else
v[k,w] = v[k-1,w]
else v[k,w] = v[k-1,w] // wk > w, object k is not used 94
Backpacking
Example (18)
k 0 1 2 3 4 Objects
W
0 0 0 0 0 0
1: (2,3)
k=4 2: (3,4)
1 0 0 0 0 0
bk = 6 3: (4,5)
2 0 3 3 3 3
wk =5 4: (5,6)
3 0 3 4 4 4
4 0 3 4 5 5 w= 5
5 0 3 7 7 7 w-wk =0
if wk <= w then // the object cannot be used
if b + v[k-1,w-wk ] > v[k-1,w] then
v[k,w] = bk + v[k-1,w-wk ]
else
v[k,w] = v[k-1,w]
else v[k,w] = v[k-1,w] // wk > w, object k is not used 95
Backpacking
• Algorithm backpack only finds the maximum total that the backpack can
hold
• Exercise
• Building the optimal solution
• The objects contained in the backpack
• Illustration k 0 1 2 3 4
W
0 0 0 0 0 0
1 0 0 0 0 0
Used objects: 1, 2
2 0 3 3 3 3
3 0 3 4 4 4
4 0 3 4 5 5
5 0 3 7 7 7
96
Exercises
• Problem 1
• Fibonacci numbers are defined
F0 = 1, F1 = 1
Fn = Fn-1 + Fn-2
Build dynamic programming algorithm computing Fn
• Problem 2
• Catalan numbers defined
1 n 1
n 1
T ( n)
T (i ).T (n i ) n 1
i 1
97
Exercises
• Problem 3
• Coin change: Given a set of coin denominations and a target amount, find the
minimum number of coins needed to make up the target amount. If it's not
possible to form the target amount, return −1 (no solution).
• Hint:
• Use an array dp[], where dp[i] represents the minimum number of coins needed to
form amount i.
• For each coin c, update dp[i] as: dp[i]=min(dp[i],dp[i−c]+1).
98
Explanation
1 n 1
n 1
P ( n)
P(k ) P(n k ) n 2
k 1
2 n 2 (do n 5)
• So P(n) = (2n )
99