# Longest Bitonic Sequence ### Call a sequence X[0:n] of numbers bitonic if there is an index i with 0<i<n, such that the prefix X[0:i] is increasing and the suffix X[i:n] is decreasing. Describe an efficient algorithm to compute the length of the longest bitonic subsequence of an arbitrary array X of integers. #### Algorithm Pseudocode ``` fun longest_bitonic_sequence (A) { var n = len(a); var lis = []; var lds = []; // base case: sequence is size <= 1 if (n <= 1) { return n; } // initializes arrays to size n and filled with ones for (int i = 0; i < n; i++) { lis[i] = 1; lds[i] = 1; } // fill up lis array for (var i = 1; i < n; i++) { for (var j = 0; j < i; j++) { if (A[i] > A[j] AND lis[i] < lis[j] + 1) lis[i] = lis[j] + 1; } } // fill up lds array for (var i = n-2; i > 0; i++){ for (var j = n-1; j > i; j++) { if (A[i] > A[j] AND lds[i] < lds[j] + 1) lds[i] = lds[j] + 1; } } // compute max subsequence length var maxLength = 0; var currentLength; for (var i = 0; i < n; i++) { currentLength = lis[i] + lds[i] - 1; if (maxLenght < currentLength) maxLenght = currentLength; } return maxLength; } ``` #### 1. Clear definition of subproblem -- e.g. T[i] defined as longest bitonic subseuqence of A[i:n], etc. The algorithm will use two DP arrays, LIS[i] and LDS[i], for the input array X[0...n-1]: * $LIS[i]$: The length of the Longest Increasing Subsequence of $X[0...n-1]$ that ends at index $i$. ($X[i]$ is the last and largest element of the sequence). * $LDS[i]$: The length of the Longest Decreasing Subsequence of $X[0...n-1]$ that starts at index $i$. ($X[i]$ is the first and largest element of the sequence). #### 2. Recursion between the subproblems in such a way that can be tabulated; e.g. T[i] = T[i+1] +1 The tables are computed as follows (using an sequence size 1 or less as the base case [returns n]): * $LIS[i] = 1 + max(\{LIS[j] \mid 0 \le j < i \text{ and } X[j] < X[i]\})$ * This is computed by iterating $i$ from $0$ to $n-1$. * $LDS[i] = 1 + max(\{LDS[j] \mid i < j < n \text{ and } X[j] < X[i]\})$ * This is computed by iterating $i$ from $n-1$ down to $0$. * The final answer is the maximum value of $LIS[i] + LDS[i] - 1$ for all $0 \le i < n$. It is -1 as the "peak" is counted in both the increasing and decreasing ssequences. #### 3. One short paragraph describing why the recursion (equality) holds. Any bitonic subsequence must have a single "peak" element $X[i]$, which is the largest element in that subsequence. The $LIS[i]$ recurrence calculates the length of the increasing "left side" of the bitonic subsequence that ends at $X[i]$. It does this by finding the longest increasing subsequence ending at some $j$ before $i$ (where $X[j] < X[i]$) and adding 1 (for $X[i]$). The $LDS[i]$ recurrence similarly calculates the length of the decreasing "right side" that starts at $X[i]$ by looking forward to elements $X[j]$ (where $j > i$ and $X[j] < X[i]$). The total length of the longest bitonic subsequence with $X[i]$ as its peak is $LIS[i] + LDS[i] - 1$. We subtract 1 because the peak $X[i]$ is counted in both the $LIS$ and $LDS$ computations. The algorithm finds this value for every possible peak $i$ and takes the maximum.