Watch 10 video solutions for Number of Ways of Cutting a Pizza, a hard level problem involving Array, Dynamic Programming, Memoization. This walkthrough by codestorywithMIK has 9,908 views views. Want to try solving it yourself? Practice on FleetCode or read the detailed text solution.
Given a rectangular pizza represented as a rows x cols matrix containing the following characters: 'A' (an apple) and '.' (empty cell) and given the integer k. You have to cut the pizza into k pieces using k-1 cuts.
For each cut you choose the direction: vertical or horizontal, then you choose a cut position at the cell boundary and cut the pizza into two pieces. If you cut the pizza vertically, give the left part of the pizza to a person. If you cut the pizza horizontally, give the upper part of the pizza to a person. Give the last piece of pizza to the last person.
Return the number of ways of cutting the pizza such that each piece contains at least one apple. Since the answer can be a huge number, return this modulo 10^9 + 7.
Example 1:

Input: pizza = ["A..","AAA","..."], k = 3 Output: 3 Explanation: The figure above shows the three ways to cut the pizza. Note that pieces must contain at least one apple.
Example 2:
Input: pizza = ["A..","AA.","..."], k = 3 Output: 1
Example 3:
Input: pizza = ["A..","A..","..."], k = 1 Output: 1
Constraints:
1 <= rows, cols <= 50rows == pizza.lengthcols == pizza[i].length1 <= k <= 10pizza consists of characters 'A' and '.' only.Problem Overview: You are given a rectangular pizza grid where each cell is either an apple ('A') or empty ('.'). The goal is to cut the pizza into k pieces using horizontal or vertical cuts so every piece contains at least one apple. Return the total number of valid ways to perform these cuts.
Approach 1: DP with Prefix Sum + Memoization (Time: O(k * m * n * (m + n)), Space: O(k * m * n))
The key difficulty is quickly checking whether a sub-rectangle contains at least one apple. A 2D prefix sum matrix solves this: it lets you query the apple count of any rectangle in constant time. With that in place, use top-down dynamic programming. Define dfs(r, c, cutsLeft) as the number of ways to cut the submatrix starting at (r, c) with cutsLeft cuts remaining.
From each state, try every possible horizontal cut below the current row and every vertical cut to the right. Before recursing, verify that the piece being separated contains at least one apple using the prefix sum lookup. Memoize the result for each state so repeated subproblems are solved once. This transforms an exponential search into a manageable dynamic programming solution. The approach combines dynamic programming, memoization, and fast region queries over a matrix.
Approach 2: Bottom-Up Dynamic Programming (Time: O(k * m * n * (m + n)), Space: O(k * m * n))
The same recurrence can be computed iteratively instead of recursion. Let dp[c][r][c] represent the number of ways to cut the submatrix starting at (r, c) into c + 1 pieces. Start with the base case where no more cuts are needed and check whether the remaining region contains an apple using the prefix sum matrix.
Then iterate through the number of cuts and accumulate ways by attempting horizontal and vertical cuts. For each candidate cut, confirm the top or left piece contains at least one apple before adding the ways from the remaining subproblem. Bottom-up DP avoids recursion overhead and can be easier to reason about during debugging, but it uses the same state transitions and complexity.
Recommended for interviews: The prefix sum + memoized DFS approach is the one most candidates implement first. It clearly expresses the recursive substructure and shows you understand pruning with fast region queries. Bottom-up DP demonstrates deeper mastery of dynamic programming state transitions, but both solutions rely on the same insight: precompute apple counts and reuse results for overlapping subproblems.
| Approach | Time | Space | When to Use |
|---|---|---|---|
| DP with Prefix Sum + Memoization | O(k * m * n * (m + n)) | O(k * m * n) | Most intuitive solution. Great for interviews and when recursion with caching is acceptable. |
| Bottom-Up Dynamic Programming | O(k * m * n * (m + n)) | O(k * m * n) | Preferred when avoiding recursion or when you want explicit control over DP state transitions. |