ACM ICPC World Finals 2013
Writeup by Onufry
Shortest judge solution: 1443 bytes. Shortest team solution (during contest): 1224 bytes.
This proved to be one of the tougher problems in the competition. The most naive solution to this problem would take Ω(n6 ) time. With very little effort, this can be improved to a Θ(n4 ) solution, but this is still too slow. Fortunately, yet another factor of n can be shaved off in the running time.
It is instructive to first consider a 1-dimensional variant of the problem. Given an array x0 , . . . , xn−1 , and a subsequence [ j, k) of it (that is, xj , . . . , xk−1 ), we are interested in the values V (k, j) := (k − j) · minj≤i<k xi . In particular, we are interested in sequences that maximize this value.
Consider a subsequence [k, j), assume that xi is the minimal value of the elements of this subsequence. If V (k, j) is a candidate to be the largest value, this means xk−1 < xi and xj < xi — otherwise we could extend the interval to get a higher V value. So now, for each i, we will calculate the longest subsequence that has its minimum at xi .
To do this, we will do a single run through the xi sequence and a use stack. We will go through the sequence, and for each element xi we will first pop all elements that are larger or equal to it from the stack, and then push xi onto the stack. This way, the elements on the stack will always be in increasing order (since we never add an element that’s smaller or equal to the one before it). When we pop an element xi from the stack, we can actually calculate the longest segment with the minimum at xi . Since we’re popping xi , the element we’re inserting (call it xk ) is necessarily smaller than xi ; and since we didn’t pop it so far, xk is the first element smaller than xi . Similarly, the element directly preceding xi in the stack (call it xj ) has to be the last element smaller than xi — if there was something between them, it wouldn’t have been popped. Thus, when we pop xi from the stack, we can add xi · (k − j − 1) as a candidate for the largest V (k, j) value. Thus, in O(n) time, we can get all candidate values for the largest V (k, j).
Now to solving the full problem. For a fixed column c, and each 1 ≤ r, t ≤ m, we can calculate minr≤s<t xc,s in O(m2 ) time, in a number of ways (like DP, incrementally increasing interval length). Let’s do it for all columns, in O(m2 n).
Now, fix the vertical dimension of the chest d, and fix the top row z in which the chest begins. Then we are interested in the highest value of d · (k − j) · minz≤s<z+d minj≤i<k xi,s . We have already precalculated what the lowest value of xi,s is for any fixed i over z ≤ s < z + d, let’s call it m(i ) (it depends on z and d as well, but we’re treating these as fixed). So, we’re interested in d · (k − j) · minz≤s<z+d m(i ) — but this is exactly the one-dimensional problem we know how to solve in linear time! Thus, we solve it for all z and d values, and obtain an O(mn max(m, n)) algorithm for the whole problem.