Problem 1 (Maximum Subarray). Given an array A[1, n] such that A[i] ∈ R, we want the two indexes i, j ∈ {1, 2, . . . , n} ∧ i ≤ j that maximize the following function: j X A[k] k=i Define B[1, n] as an array such that B[i] = n X A[i]. (1) k=i Observation 1. Given two indexes i, j such that i > j, j−1 X A[i] = B[i] − B[j]. (2) k=i So we can restate the problem as find the two indexes i, j ∈ {1, 2, . . . , n} ∧ i ≤ j that maximize the function B[i] − B[j + 1]. The Algorithm We start to scan the array B in reverse order, from the index n to 1. Suppose that the sub-array B[i − 1, n] have been visited, and that in this sub-array the indexes k1 , k2 maximize B[K1 ] − B[K2 ] with K1 ≤ K2 ∈ {i − 1, i − 2, . . . , n} (in other words, we know solution of the problem for this sub-array). Suppose that B[m] with i ≤ m ≤ k2 is the element such that B[m] = minj=i,i−1,...,k2 {B[j]}. Lemma 1. If B[i] > B[k1 ] − B[k2 ] + B[m] then the problem for the sub-array B[i, n] has solution i, max{m − 1, 1}. Else the solution is still k1 , max{k2 − 1, 1}. Proof. B[i] > B[k1 ] − B[k2 ] − B[m] ⇒ B[i] − B[m] > B[k1 ] − B[k2 ], (3) So the cost of the new sub-array is improved than the old optimal sub-array, this means that the cost of the new sub-array is also better than the cost of all sub-arrays that contain indexes into the range i − 1 to n. We have to prove that is also better than subarrays that start with index i. This is surely true because the index m is the minimum minj=i,i−2,...,n {B[j]} for construction; infact B[k2 ] = minj=k1 ,i−1,...,n {B[j]} (otherwise k1 , k2 − 1 is not optimal for the old sub-array) and we know that B[m] ≤ B[k2 ] ∧ B[m] = minj=i,i−1,...,k1 −1 {B[j]}. In the case that B[i] ≤ B[k1 ] − B[k2 ] + B[m] we cannot improve the objective function of the old sub-array. 1 c 2011/2012 Roberto Ladu n Lemma 2. The following algorithm solve the problem in O(n) steps and O( ) I/Os. B 1 2 3 i n t A [ 1 , n ] // i n p u t i n t B [ 1 , n ] // s u p p o r t a r r a y (A can be a l s o r e w r i t t e n space saved ) i n t c , k 1 , k 2 , m, k , i ; and 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 c = 0; f o r ( i=n ; i >=1; i −−){ c = c + A[ i ] ; B [ i ] = c ; } // t h e a r r a y B i s b u i l t k 1 = n; k 2 = n ; // i n i t i a l i z a t i o n t o max s u b s e q u e n c e A [ n , n ] f o r ( i=n ; i >=1; i −−){ i f (B [ i ]<B [ k 2 ] ) { m = i; k = B [ k 1 ] − (B [ k 2 ] − B [m] ) ; } i f (S [ i ] > k ){ k 1 = i; k 2 = m; k = B[ k 1 ]}} The algorithm is correct. By induction. At the first step k1 = k2 = n are the maximum subsequence. Then because m is at every step the minimum B[j], using Lemma 1 we can prove that when i = 1 the solution is found. Complexity. The array is scanned left to right exactly two times: one for build B and n the other for find the indexes. This imply also that the number of I/Os is , we can B reduce the accesses that are not consecutive (like when S[k1 ] is read at line 18) using more variables. 2 c 2011/2012 Roberto Ladu