Find a subsequence of a given sequence such that the subsequence sum is as high as possible and the subsequence’s elements are sorted in ascending order. This subsequence is not necessarily contiguous or unique.

Please note that the problem specifically targets subsequences that need not be contiguous, i.e., subsequences are not required to occupy consecutive positions within the original sequences.

For example, consider subsequence {0, 8, 4, 12, 2, 10, 6, 14, 1, 9, 5, 13, 3, 11}. The maximum sum increasing subsequence is {8, 12, 14} which has sum 34.

Practice this problem

The Maximum Sum Increasing Subsequence (MSIS) problem is a standard variation of the Longest Increasing Subsequence (LIS) problem. The idea is to use recursion to solve this problem. For each item, there are two possibilities:

  1. Include the current item in MSIS if it is greater than the previous element in MSIS and recur for the remaining items.
  2. Exclude the current item from MSIS and recur for the remaining items.

Finally, return the maximum sum we get by including or excluding the current item. The base case of the recursion would be when no items are left. Following is the C++, Java, and Python implementation of the idea:

C++


Download  Run Code

Output:

The maximum sum of the increasing subsequence is 34

Java


Download  Run Code

Output:

The maximum sum of the increasing subsequence is 34

Python


Download  Run Code

Output:

The maximum sum of the increasing subsequence is 34

The time complexity of the above solution is exponential and occupies space in the call stack.

 
The problem has optimal substructure. That means the problem can be broken down into smaller, simple “subproblems”, which can further be divided into yet simpler, smaller subproblems until the solution becomes trivial. The above solution also exhibits overlapping subproblems. If we draw the solution’s recursion tree, we can see that the same subproblems are repeatedly computed.

We know that problems with optimal substructure and overlapping subproblems can be solved using dynamic programming, in which subproblem solutions are memoized rather than repeatedly computed. The memoized version follows the top-down approach since we first break the problem into subproblems and then calculate and store values.

 
We can also solve this problem in a bottom-up manner. In the bottom-up approach, we solve smaller subproblems first, then solve larger subproblems from them. The following bottom-up approach computes sum[i], for each 0 <= i < n, which stores the maximum sum of an increasing subsequence of subarray nums[0…i] that ends with nums[i]. To calculate the sum[i], consider MSIS of all smaller values of i (say j) already computed and pick maximum sum[j], where nums[j] is less than the current element nums[i] and add current element nums[i] to it. It has the same asymptotic runtime as Memoization but no recursion overhead.

Following is the C++, Java, and Python implementation of the idea:

C++


Download  Run Code

Output:

The maximum sum of the increasing subsequence is 34

Java


Download  Run Code

Output:

The maximum sum of the increasing subsequence is 34

Python


Download  Run Code

Output:

The maximum sum of the increasing subsequence is 34

The time complexity of the above solution is O(n2) and requires O(n) extra space, where n is the size of the given sequence.

How to print MSIS?

The above-discussed methods only print the sum of MSIS but do not actually print MSIS itself. To print the MSIS, we actually have to store the maximum sum increasing subsequence in the lookup table along with storing the maximum sum.

For example, consider nums = [ 8, 4, 12, 2, 10, 6, 14, 1, 9, 5, 13, 3, 11 ]. The maximum sum increasing subsequence MSIS[i] of subarray nums[0…i] that ends with nums[i] are:

MSIS[0] — 8
MSIS[1] — 4
MSIS[2] — 8 12
MSIS[3] — 2
MSIS[4] — 8 10
MSIS[5] — 4 6
MSIS[6] — 8 12 14
MSIS[7] — 1
MSIS[8] — 4 6 9
MSIS[9] — 4 5
MSIS[10] — 8 12 13
MSIS[11] — 2 3
MSIS[12] — 4 6 9 11

Following is the C++, Java, and Python implementation of the idea:

C++


Download  Run Code

Output:

8 12 14

Java


Download  Run Code

Output:

[8, 12, 14]

Python


Download  Run Code

Output:

[8, 12, 14]

The time complexity of the above solution is O(n2) and requires O(n2) extra space, where n is the size of the given sequence.