Problem Description
You are given an n x n grid of non‐negative integers. Initially every cell is white. In one operation you may pick any cell (i, j) and “paint” the jth column from the top down to row i black. After doing an arbitrary number of these operations the score is computed as the sum of all white cells that have at least one horizontally adjacent (left or right) cell that is black. The goal is to choose operations (i.e. choose for each column a “cut‐off” row up to which that column becomes black) so that the overall score is maximized.
Key Insights
- Each column’s operation is equivalent to choosing a threshold (or “cut”) such that rows above (and including) the chosen cell become black and the rest remain white.
- After all operations, every column j is fully described by its “transition” row r[j] where row i is white if and only if i ≥ r[j]. (For a column never painted, r[j]=0 so that the entire column is white.)
- A white cell in row i, column j contributes to the score only if at least one of its horizontal neighbors (column j‑1 or j+1) is still black at row i (i.e. if i < r[neighbor]).
- Notice that although each column’s choice is “local” in the sense that it just sets its own white–black boundary, the scoring function couples adjacent columns.
- The optimal solution requires balancing: a column may sacrifice some of its own potential white cell values (by choosing a low r[j] and hence having few white cells) so as to help count high‐value white cells in its neighbour.
- The dependencies among adjacent columns naturally lead to a dynamic programming formulation where the decision for column j depends on the choices for columns j–1 (and even j–2 when computing the score contribution for column j–1).
Space and Time Complexity
Time Complexity: O(n * (n+1)^3)
(n columns; each threshold is in the range [0,n] and a DP state may depend on two neighbors.)
Space Complexity: O(n * (n+1)^2)
(space used for the DP states)
Solution
We solve the problem by reinterpreting an “operation” as choosing, for each column j, a transition row r[j] (with 0 ≤ r[j] ≤ n). For column j the cells in rows 0..r[j]-1 become black and rows r[j]..n-1 remain white. Then, a white cell (i, j) contributes its grid value if and only if one of its horizontal adjacent cells is black at row i. In terms of r-values, this means that if j is not a boundary column, white cell (i,j) contributes when i is at least r[j] and strictly less than the r-value in at least one neighbor (i.e. i < max(r[j-1], r[j+1])). For the first and last columns the condition uses the single available neighbor.
Since the contribution from a column’s white cells depends on the r-value chosen for that column as well as on the neighbors’ r-values, we set up a dynamic programming (DP) solution. The idea is to process the columns left to right while “remembering” the r-value chosen for the previous column (and even the one before that) so that when the next column’s r-value is chosen we can “finalize” the contribution from the previous column.
Before starting the DP we precompute the prefix sums for every column to quickly compute the sum of grid values between any two row indices. The DP recurrence is defined over states that capture the thresholds chosen for the last two columns. For a state corresponding to having fixed r[j-2] and r[j-1], when deciding r[j] we can compute the contribution from column j-1. In the interior (non-boundary) case, the white cells in column j-1 that are “counted” come from the rows in [r[j-1], max(r[j-2], r[j])-1] (if that interval is valid). Similar ideas are applied at the boundaries (for the very first and last columns).
Note that one “gotcha” is to ensure that you add the grid values only once even if both neighbors are black. Also, be cautious with boundary conditions (first and last columns have only one neighbor).
The final answer will be the maximum total score over all valid choices of r-values.