Monday, February 4, 2013

Notes on LCS, LIS, and related problems

LCS (Longest Common Subsequence) is a well-known dynamic programming(DP) problem. I learned it several times, but sadly I forgot it several times as well. These kinds of problems are not that straightforward for someone first encounters it. While I'm learning(to be more specific, re-learning) these related problems recently, I still haven't found any short path to master DP algorithms. Personally, I think completely understanding more and more problems will enlarge our knowledge to solve other similar problems in the future. And of course, coding is inevitable and essential.

Circus Tower Sorting Problem
There are many interesting problems related to LCS problem. For example:
A circus is designing a tower routine consisting of people standing atop
one another’s shoulders. For practical and aesthetic reasons, each
person must be both shorter and lighter than the person below him or
her. Given the heights and weights of each person in the circus, write a
method to compute the largest possible number of people in such a
tower.
EXAMPLE:
Input (ht, wt): (65, 100) (70, 150) (56, 90) (75, 190) (60, 95) (68, 110)
Output: The longest tower is length 6 and includes from top to bottom: (56, 90) (60,95) (65,100) (68,110) (70,150) (75,190)

This problem can be easily converted to LCS problem and therefore solution is quite simple:

Sort the data according to height. Denote it as D1. That is O(nlogn).

Sort the data according to weight. Denote it as D2. That is O(nlogn).

Find the length of the LCS of D1 and D2. Using dynamic programming, it’s O(n^2).

Given a good understanding of LCS problem, this problem can be solved quickly, though it's tricky.

Sort the Sequence in increasing order. Denote it as S'. That is O(nlogn).

Find the length of the LCS of original sequence S and S'. Using dynamic programming, it’s O(n^2).

This reveals the overall O(n^2) time complexity solution. Another O(n^2) DP solution is shown here. There's exists O(nlogn) solution to solve it and that's not hard either. They can be found on wiki and a good example is shown on a Chinese blog.

You have a stack of n boxes, with width w(i), depth d(i), and height h(i). The boxes cannot be rotated and can only be stacked on top of one another if each box in the stack is strictly larger than the box above it in width, height, and depth. Implement a method to build the tallest stack possible, where the height of a stack is the sum of the heights of each box.

My initial thought is to adapt a similar approach as the Circus Tower problem. However, sorting the boxes in width, depth and height separately and find their LCS is kind of 3-Dimension DP, which is much more complicated. Actually I don't if it will truly work.

While answer in the book is taking the similar idea of solving LIS problem, I don't understand it well, and I don't like the code either. So I just put my idea here:

1. Sort the boxes on increasing order of height.
2. Let:
H(i) = Maximum possible Stack Height with box i at bottom of stack
H(i) = { Max ( H(j) ) + height(i) }
where j is in [1..i-1] and width(j) < width(i) and depth(j) < depth(i) and height(j) < height(i)
If there is no such j then H(i) = height(i).
3. Scan H(1) to H(n). Find the max as the answer.