Design and Analysis of Algorithms
. . !"#
2542
!" ## $%&'(()#* &$(+!$ ,* "&'(
-"*%##++(& %# .#
.$'/(0 1$ /-1 %#%
Dynamic Programming
Maximum Sum Problem
Outline
Maximum sum problem Brute force
Divide and conquer Dynamic programming Conclusion
Maximum Sum Problem
Input : A [1.. n ] an array of n real numbers Output : maximum sum in any contiguous
subvector of the input
(31, -41, 59, 26, -53, 58, 97, -93, -23, 84) 59+26 - 53+58+97 = 187 (max)
Brute Force
'()*+,- subvectors : ./*01)2.34*5678 ? subvectors */:;6< 1, 2, 3, ..., n ./=>6?<? n , n -1,
n -2, ..., 1 @+3A6.'>630B
./*01)2.3 n +( n -1)+...+1 = " ( n 2 ) subvectors sum C() subvectors */:;6< k 2673D=6,C()*/:;6<
k -1 26EA5'F sum G@D O(1)
Brute force : " ( n 2 )
Brute Force
MaxSum( A[1..n] ) {
S[1][1..n] = A[1..n]
for i=2 to n for j=1 to n-i+1
s[i][j] = s[i-1][j] + A[j+i-1]
}
ms = max( S[1][1..n] )
if ( ms < s[i][j] ) ms = s[i][j]
return ms
Brute Force
MaxSum( A[1..n] ) {
S[1][1..n] = A[1..n]
ms = max( S[1][1..n] ) for i=2 to n
for j=1 to n-i+1
s[i][j] = s[i-1][j] + A[j+i-1]
if ( ms < s[i][j] ) ms = s[i][j]
return ms }
Brute Force
MaxSum( A[1..n] ) {
S[1..n] = A[1..n]
ms = max( S[1..n] ) for i=2 to n for j=1 to n-i+1 s[j] = s[j] + A[j+i-1]
if ( ms < s[j] ) ms = s[j]
return ms }
Divide and Conquer
EB5)H8I:) array 4JK?@+3LD6; @+3C<6 26 max. sum @+3LD6; : S L
26 max. sum @+3C<6 : S R 26 max. sum */:CD6.NOQ) : S M H>6A(BHR( max( S L , S R , S M )
Divide and Conquer
31, -41, 59, 26, -53, 58, 97, -93, -23, 84 31, -41, 59, 26 , -53
58, 97 , -93, -23, 84 31, -41, 59, 26, -53, 58, 97 , -93, -23, 84 max. sum = max ( 85, 155, 187 ) = 187
Divide and Conquer
26 S L E'F S R 4JK? recursive calls LI:)=F2;+34.R:(./
CD(.T'A0<43/;<
T( n ) = 2 T( n /2 ) + (4<'6*/:G@D26 S M ) Master method : 26 S M 7.5H<8G@D4,W? O( n )
XD6A>:6,<56 " ( n ) 73D T( n ) = " ( n ) ( ) XD64*56,0B " ( n ) 73D T( n ) = " ( n log n )
JOY26 : =F26 S M G? linear time 73D(;56)78 ?
S M ( n )
A : 31,-41, 59, 26,-53, 58, 97,-93,-23, 84
a b
c = (a + b)/2 c
S M ( n )
A : 31,-41, 59, 26,-53, 58, 97,-93,-23, 84 M : -53
M[c] = A[c]
a c b
S M ( n )
A : 31,-41, 59, 26,-53, 58, 97,-93,-23, 84 M : -27,-53
for ( i=c-1 downto a ) M[i] = M[i+1] + A[i]
M[c] = A[c]
a c b
S M ( n )
A : 31,-41, 59, 26,-53, 58, 97,-93,-23, 84 M : 32,-27,-53
a b
M[c] = A[c]
for ( i=c-1 downto a ) M[i] = M[i+1] + A[i]
c
S M ( n )
A : 31,-41, 59, 26,-53, 58, 97,-93,-23, 84 M : -9, 32,-27,-53
a b
M[c] = A[c]
for ( i=c-1 downto a ) M[i] = M[i+1] + A[i]
c
S M ( n )
A : 31,-41, 59, 26,-53, 58, 97,-93,-23, 84 M : 22, -9, 32,-27,-53
a b
M[c] = A[c]
for ( i=c-1 downto a ) M[i] = M[i+1] + A[i]
c
S M ( n )
A : 31,-41, 59, 26,-53, 58, 97,-93,-23, 84 M : 22, -9, 32 32 32 32,-27,-53
a b
left = max_I( A[a..c] ) c
S M ( n )
A : 31,-41, 59, 26,-53, 58, 97,-93,-23, 84 M : 22, -9, 32 32 32 32,-27,-53, 58
a b
M[c+1] = A[c+1]
c
S M ( n )
A : 31,-41, 59, 26,-53, 58, 97,-93,-23, 84 M : 22, -9, 32 32 32 32,-27,-53, 58,155
a b
for ( i=c+2 to b ) M[i] = M[i-1] + A[i]
M[c+1] = A[c+1]
c
S M ( n )
A : 31,-41, 59, 26,-53, 58, 97,-93,-23, 84 M : 22, -9, 32 32 32 32,-27,-53, 58,155, 62
a b
M[c+1] = A[c+1]
for ( i=c+2 to b ) M[i] = M[i-1] + A[i]
c
S M ( n )
A : 31,-41, 59, 26,-53, 58, 97,-93,-23, 84 M : 22, -9, 32 32 32 32,-27,-53, 58,155, 62, 39
a b
M[c+1] = A[c+1]
for ( i=c+2 to b ) M[i] = M[i-1] + A[i]
c
S M ( n )
A : 31,-41, 59, 26,-53, 58, 97,-93,-23, 84 M : 22, -9, 32 32 32 32,-27,-53, 58,155, 62, 39,123
a b
M[c+1] = A[c+1]
for ( i=c+2 to b ) M[i] = M[i-1] + A[i]
c
S M ( n )
A : 31,-41, 59, 26,-53, 58, 97,-93,-23, 84 M : 22, -9, 32 32 32 32,-27,-53, 58,155 155 155 155, 62, 39,123
a b
rght = max_I( A[c+1..b] ) c
S M ( n )
A : 31,-41, 59, 26,-53, 58, 97,-93,-23, 84 M : 22, -9, 32 32 32 32,-27,-53, 58,155 155 155 155, 62, 39,123 59, 26,-53, 58, 97
a c b
S M ( n )
MaxSum_M( A[a..b] ) {
c = (a+b)/2 M[c] = A[c]
for ( i=c-1 downto a ) M[i] = M[i+1] + A[i]
M[c+1] = A[c+1]
for ( i=c+2 to b ) M[i] = M[i-1] + A[i]
left = max_I( A[a..c] ) rght = max_I( A[c+1..b] ) return M[ left ] + M[ rght ] }
Divide and Conquer
MaxSum_DQ( A[a..b] ) {
if ( a == b ) return A[a]
c = (a+b)/2
SL = MaxSum_DQ( A[a..c] ) SR = MaxSum_DQ( A[c+1..b] ) SM = MaxSum_M( A[a..b] ) return max( SL, SR, SM )
} "
( n log n )
MaxSum( A[1..n] )
return MaxSum_DQ( A[1..n] )
Dynamic Programming
Linear-time Fill in a 1D array
Let P [ i ] = max. sum of subvectors ending at i P [ i ] = max( P [ i -1]+ A [ i ], A [ i ] )
( 2, 1, -4 , 2, -1, 5) : P [3] = -1
(2, 1, -4, 2 , -1, 5) : P [4] = max(-1+2,2)= 2 (2, 1, -4, 2, -1 , 5) : P [5] = max(2-1,-1)= 1 (2, 1, -4, 2, -1, 5 ) : P [6] = max(1+5,5)= 6
Dynamic Programming
Let S [ i ] be the max. sum of A [1 ..i ] The answer is S [ n ]
S [ i ] = max( P [ i ], S [ i -1] )
i
S [ i -1] P [ i ]
Dynamic Programming
( 2, 1, -4 , 2, -1, 5) P [3] = -1 ( 2, 1 , -4, 2, -1, 5) S[3] = 3 (2, 1, -4, 2 , -1, 5) P [4] = 2
( 2, 1 , -4, 2, -1, 5) S [4] = max( 2, 3)= 3 (2, 1, -4, 2, -1 , 5) P [5] = 1
( 2, 1 , -4, 2, -1, 5) S [5] = max( 1 , 3)= 3 (2, 1, -4, 2, -1, 5 ) P [6] = 6
(2, 1, -4, 2, -1, 5 ) S [6] = max( 6 , 3)= 6
Max. Sum : Dynamic Programming
MaxSum( A[1..n] ) {
P[1] = A[1]
for ( i=2 to n )
P[i] = max( P[i-1]+A[i], A[i] ) S[1] = A[1]
for ( i=2 to n )
S[i] = max( s[i-1], P[i] ) return S[n]
} "
( n )
Max. Sum : Dynamic Programming
MaxSum( A[1..n] ) {
P = A[1]
S = A[1]
for ( i=2 to n ) { P = max( P+A[i], A[i] ) S = max( S, P ) }
return S
} "
( n )
Conclusion
Maximum sum problem Brute force : " ( n 2 )
Divide and conquer : " ( n log n ) Dynamic programming : " ( n )
Homework
Algorithms *01)EBB brute force, divide and conquer E'F dynamic programming */:?>64^?(
return H56 sum */:.6,^+3
=)J80BJ8+) algorithms *01)^6. 4_R:(HR? subvector
*/:4JK? max. sum