Given an array, find maximum sum increasing subsequence in this array.
Solution 1. Recursion
For arr[0....n], the max sum increasing subsequence can be computed from first computing its subarrays' max sum increasing subsequence.
MaxSumIncreSubseq(n) = max {arr[n], max of {MaxSumIncreSubseq(i) + arr[n], for i from 0 to n - 1}};
1 public int getMaxSumIncreSubseqRecursion(int[] arr) { 2 if(arr == null || arr.length == 0) { 3 return 0; 4 } 5 int maxSum = Integer.MIN_VALUE; 6 for(int i = 0; i < arr.length; i++) { 7 int sum = recursiveHelper(arr, i); 8 maxSum = Math.max(maxSum, sum); 9 } 10 return maxSum; 11 } 12 private int recursiveHelper(int[] arr, int endIdx) { 13 int max = arr[endIdx]; 14 for(int i = 0; i < endIdx; i++) { 15 if(arr[i] < arr[endIdx]) { 16 max = Math.max(max, recursiveHelper(arr, i) + arr[endIdx]); 17 } 18 } 19 return max; 20 }
Solution 2. Dynamic Programming
State: T[i]: the max sum of increasing subsequence that ends with arr[i].
Function: T[i] = max of T[j] + arr[i], for j from 0 to i - 1, if arr[j] < arr[i];
Init: T[i] = arr[i], as we always know one of the increasing subsequence that ends with arr[i] is itself without other elements.
Answer: max of T[i].
1 import java.util.ArrayList; 2 3 public class MaxSumIncreasingSubseq { 4 private ArrayList<Integer> maxSumSubseq; 5 public int getMaxSumIncreSubseqDp(int[] arr) { 6 if(arr == null || arr.length == 0) { 7 return 0; 8 } 9 int[] T = new int[arr.length]; 10 int[] seqIdx = new int[arr.length]; 11 for(int i = 0; i < T.length; i++) { 12 T[i] = arr[i]; 13 seqIdx[i] = i; 14 } 15 for(int i = 0; i < T.length; i++) { 16 for(int j = 0; j < i; j++) { 17 if(arr[j] < arr[i]) { 18 if(T[j] + arr[i] > T[i]) { 19 T[i] = T[j] + arr[i]; 20 seqIdx[i] = j; 21 } 22 } 23 } 24 } 25 int max = Integer.MIN_VALUE; 26 int maxIdx = -1; 27 for(int i = 0; i < arr.length; i++) { 28 if(T[i] > max) { 29 max = T[i]; 30 maxIdx = i; 31 } 32 } 33 maxSumSubseq = new ArrayList<Integer>(); 34 int currIdx = maxIdx; 35 while(currIdx != seqIdx[currIdx]) { 36 maxSumSubseq.add(currIdx); 37 currIdx = seqIdx[currIdx]; 38 } 39 maxSumSubseq.add(currIdx); 40 return max; 41 } 42 }
Related Problems