Overview
Grid DP computes an answer for every cell of a matrix from its neighbors, usually the cell above and the cell to the left when movement is restricted to right and down. dp[r][c] might be the number of paths to the cell, the minimum cost to reach it, or the size of the largest square ending there.
Because each row depends only on the previous row, grid DP almost always compresses to a single 1D array of length cols. More advanced variants add a third dimension, such as two walkers moving together (Cherry Pickup) or remaining steps.
If you can only walk east or south, the number of ways to reach an intersection is the ways to reach the intersection to its west plus the ways to reach the one to its north. Fill in the map row by row and the office corner holds the answer.
When to use it
- Movement is restricted (right / down, or down with diagonals).
- Count paths, minimize path cost, or maximize collected value.
- Largest square or rectangle of 1s ending at each cell.
- Obstacles block some cells.
Problem patterns it solves
Recognize it when: number of ways from top-left to bottom-right.
- 62. Unique Paths
- 63. Unique Paths II
- 1289. Minimum Falling Path Sum II
Recognize it when: cheapest path with right / down moves.
- 64. Minimum Path Sum
- 120. Triangle
- 931. Minimum Falling Path Sum
Recognize it when: dp = 1 + min(top, left, top-left).
- 221. Maximal Square
- 1277. Count Square Submatrices with All Ones
Recognize it when: minimum starting value to survive a path.
- 174. Dungeon Game
Recognize it when: two paths at once or a step limit.
- 741. Cherry Pickup
- 1463. Cherry Pickup II
- 576. Out of Boundary Paths
Recognize it when: longest increasing path moving in 4 directions.
- 329. Longest Increasing Path in a Matrix
Where it is used in real software
Content-aware image resizing removes the lowest-energy vertical seam, found with grid DP over pixel energies.
Counting or costing paths through a warehouse grid with obstacles.
Checking reachability and optimal collectible routes in tile-based levels.
Finding the cheapest route across a cost map (elevation, risk) with restricted movement.
Key terms
- dp[r][c]
- Answer for paths ending at cell (r, c).
- First row / column
- Base cases: reachable only in one direction.
- Obstacle
- A blocked cell whose dp value is 0 (paths) or Infinity (cost).
- Rolling row
- dp[c] holds the current row; dp[c - 1] is the left cell and old dp[c] is the cell above.
How it works, step by step
- 1Define the cell meaning
dp[r][c] = number of paths from (0, 0) to (r, c).
- 2Base cases
dp[0][0] = 1; the first row and column each have one path unless blocked.
- 3Transition
dp[r][c] = dp[r - 1][c] + dp[r][c - 1] (or min / max for costs).
- 4Handle obstacles
If the cell is blocked, dp[r][c] = 0.
- 5Compress
dp[c] += dp[c - 1] row by row gives O(cols) space.
Minimum path sum
grid = [[1, 3, 1], [1, 5, 1], [4, 2, 1]]; dp shows minimum cost to reach each cell
| Row | col 0 | col 1 | col 2 |
|---|---|---|---|
| 0 | 1 | 1 + 3 = 4 | 4 + 1 = 5 |
| 1 | 1 + 1 = 2 | min(4, 2) + 5 = 7 | min(5, 7) + 1 = 6 |
| 2 | 2 + 4 = 6 | min(7, 6) + 2 = 8 | min(6, 8) + 1 = 7 |
NOWRow: 0 | col 0: 1 | col 1: 1 + 3 = 4 | col 2: 4 + 1 = 5
Minimum cost 7 via 1 -> 3 -> 1 -> 1 -> 1. Each cell took the cheaper of arriving from above or from the left.
Implementation
function uniquePathsWithObstacles(grid) { const cols = grid[0].length; const dp = new Array(cols).fill(0); dp[0] = 1; for (const row of grid) { for (let c = 0; c < cols; c++) { if (row[c] === 1) dp[c] = 0; // obstacle else if (c > 0) dp[c] += dp[c - 1]; // above (old dp[c]) + left } } return dp[cols - 1];} function minPathSum(grid) { const rows = grid.length, cols = grid[0].length; const dp = new Array(cols).fill(Infinity); dp[0] = 0; for (let r = 0; r < rows; r++) { for (let c = 0; c < cols; c++) { const left = c > 0 ? dp[c - 1] : Infinity; dp[c] = grid[r][c] + Math.min(dp[c], left); } } return dp[cols - 1];} function maximalSquare(matrix) { const rows = matrix.length, cols = matrix[0].length; const dp = Array.from({ length: rows + 1 }, () => new Array(cols + 1).fill(0)); let best = 0; for (let r = 1; r <= rows; r++) { for (let c = 1; c <= cols; c++) { if (matrix[r - 1][c - 1] === "1") { dp[r][c] = 1 + Math.min(dp[r - 1][c], dp[r][c - 1], dp[r - 1][c - 1]); best = Math.max(best, dp[r][c]); } } } return best * best;}Complexity and performance
Constant work per cell.
One rolling row.
Cherry Pickup state (step, r1, r2).
Trade-offs
Right/down movement has a natural fill order, so bottom-up is simplest. When movement can go in any direction but values must increase, memoized DFS avoids finding an order manually.
Unique paths without obstacles equals C(m + n - 2, m - 1), computable directly.
Variants and related techniques
Bottom-up from the last row: dp[c] = row[c] + min(dp[c], dp[c + 1]).
Each cell may come from three cells above (left diagonal, above, right diagonal).
Build histogram heights per row and apply the monotonic stack rectangle algorithm.
Common mistakes
- Initializing the whole first row to 1 when an obstacle exists.
Fix: Cells after an obstacle in the first row are unreachable (0).
- Forward-filling when the constraint depends on the future.
Fix: Dungeon Game must be filled from the goal backward.
- Recursion without memoization on grids.
Fix: Plain recursion is exponential; cache each cell.
Interview questions
How do you compress grid DP to one row?
When dp[r][c] depends on dp[r - 1][c] and dp[r][c - 1], a single array works: before updating, dp[c] still holds the value from the row above, and dp[c - 1] already holds the current row's left value.
Why must Dungeon Game be solved backward?
The health needed at a cell depends on what comes after it. Going forward you would have to track both current health and minimum health, while going backward gives a single well-defined value per cell.
Practice problems
| Problem | Difficulty | What it trains |
|---|---|---|
| 62. Unique Paths | Medium | Counting paths. |
| 63. Unique Paths II | Medium | Obstacles. |
| 64. Minimum Path Sum | Medium | Min cost. |
| 221. Maximal Square | Medium | Three-neighbor min. |
| 329. Longest Increasing Path in a Matrix | Hard | Memoized DFS. |
| 174. Dungeon Game | Hard | Backward DP. |