Number of Ways of Cutting a Pizza - DP & Prefix Sum [JS]
- Get link
- X
- Other Apps
By
Anna An
on
Solution: DP - Recursion w/ Memoization & Prefix Sum
Populate
appleCount
using prefix sum, whereappleCount[i][j] = the number of apples in the piece with top left corner (i, j) and bottom right corner (n - 1, m - 1)
.
The formulaappleCount[i][j] = appleCount[i][j + 1] + appleCount[i + 1][j] - appleCount[i + 1][j + 1] + curr
means:- count = right count + bottom count - bottom right count.
- we add the right count and bottom count because we want to take the full sum.
- we subtract the bottom right count because in the right count and bottom count, the bottom right count is added on twice.
Memoize each
dp(i, j, k)
, wheredp(i, j, k) = the number of ways to cut piece with top left corner (i, j) and bottom right corner (n - 1, m - 1) with k cuts left
.i = the row number
j = the column number
k = the amount of cuts we have left
For each
dp(i, j, k)
, count the number of ways after cutting at each row and column.- Make sure the piece we are cutting contains at least one apple.
- We can check this by checking whether the
appleCount[newRow][newColumn] > appleCount[row][column]
. - If
appleCount[newRow][newColumn]
is equal toappleCount[row][column]
, we know the piece we are taking has no apples.
- We can check this by checking whether the
- Make sure the piece we are cutting contains at least one apple.
m = number of rows
, n = number of columns
Time Complexity: O(mnk * (m + n))
146ms
Space Complexity: O(mnk)
44.5MB
var ways = function(pizza, k) {
let m = pizza.length, n = pizza[0].length, mod = 10 ** 9 + 7;
let appleCount = Array(m + 1).fill(0).map(() => Array(n + 1).fill(0));
let memo = Array(m).fill(0).map(() => Array(n).fill(0).map(() => Array(k + 1).fill(-1)));
for (let i = m - 1; i >= 0; i--) {
for (let j = n - 1; j >= 0; j--) {
let curr = pizza[i][j] === 'A' ? 1 : 0;
appleCount[i][j] = appleCount[i][j + 1] + appleCount[i + 1][j] - appleCount[i + 1][j + 1] + curr;
}
}
return dp(0, 0, k);
function dp(i, j, k) {
if (k === 1) return appleCount[i][j] > 0 ? 1 : 0;
if (appleCount[i][j] === 0) return 0;
if (memo[i][j][k] !== -1) return memo[i][j][k];
let ans = 0;
for (let newRow = i; newRow < m - 1; newRow++) {
if (appleCount[newRow + 1][j] === appleCount[i][j]) continue; // top piece has no apples
ans = (ans + dp(newRow + 1, j, k - 1)) % mod;
}
for (let newCol = j; newCol < n - 1; newCol++) {
if (appleCount[i][newCol + 1] === appleCount[i][j]) continue; // left piece has no apples
ans = (ans + dp(i, newCol + 1, k - 1)) % mod;
}
return memo[i][j][k] = ans;
}
};
javascript
- Get link
- X
- Other Apps
Comments
Post a Comment