09. Chocolate Pickup II
β GFG solution to the Chocolate Pickup II problem: maximize chocolates collected by a robot traveling to bottom-right and back to top-left using optimal path selection with DP. π
The problem can be found at the following link: π Question Link
π§© Problem Description
You are given a square matrix mat[][] of size n Γ n, where each cell represents either a blocked cell or a cell containing some chocolates. If mat[i][j] equals -1, then the cell is blocked and cannot be visited. Otherwise, mat[i][j] represents the number of chocolates present in that cell.
The task is to determine the maximum number of chocolates a robot can collect by:
Starting from the top-left cell
(0, 0)Moving to the bottom-right cell
(n-1, n-1)Returning back to
(0, 0)
Movement Rules:
Forward journey
(0,0) β (n-1,n-1): Robot can move only right(i, j+1)or down(i+1, j)Return journey
(n-1,n-1) β (0,0): Robot can move only left(i, j-1)or up(i-1, j)
Important: After collecting chocolates from a cell (i, j), that cell becomes empty (mat[i][j] = 0) for the next visit. If there is no valid path for either journey, return 0.
π Examples
Example 1
Input: mat[][] = [[0, 1, -1],
[1, 1, -1],
[1, 1, 2]]
Output: 7
Explanation: Optimal path: (0,0) β (1,0) β (2,0) β (2,1) β (2,2) β (2,1) β (1,1) β (0,1) β (0,0)
Total chocolates = 0 + 1 + 1 + 1 + 2 + 0 + 1 + 1 + 0 = 7Example 2
Input: mat[][] = [[1, 1, 0],
[1, 1, 1],
[0, 1, 1]]
Output: 7
Explanation: One optimal path collects chocolates: 1 + 1 + 0 + 1 + 1 + 1 + 1 + 1 + 0 = 7Example 3
Input: mat[][] = [[1, 0, -1],
[2, -1, -1],
[1, -1, 3]]
Output: 0
Explanation: No valid path exists to reach (2,2) from (0,0) due to blocked cells.π Constraints
$1 \le n \le 50$
$-1 \le \text{mat}[i][j] \le 100$
β
My Approach
The optimal solution treats this as a simultaneous two-robot path problem using Dynamic Programming with Memoization:
Coordinate Transformation Strategy
Key Insight: Instead of simulating forward and return journeys separately, we can model this as two robots moving simultaneously from
(0,0)to(n-1,n-1).State Representation:
Track robot 1 at position
(i1, j1)and robot 2 at position(i2, j2)Use coordinate transformation: If both robots have moved the same total distance, then
i1 + j1 = i2 + j2This reduces state space to
(i1, j1, j2)wherei2 = i1 + j1 - j2
Movement Transitions:
Each robot has 2 choices at each step: move down or move right
Total combinations: 2 Γ 2 = 4 possible transitions per state
Direction encoding:
d=0means down,d=1means right
Chocolate Collection:
If robots are at the same cell
(i1 == i2 && j1 == j2): collect chocolates only onceIf robots are at different cells: collect from both cells
Base Cases:
If any robot goes out of bounds or hits a blocked cell: return very negative value
If robot 1 reaches
(n-1, m-1)and both robots are at the same position: returnmat[n-1][m-1]
Memoization:
Cache results in 3D DP table
dp[i1][j1][j2]Avoid recomputation of overlapping subproblems
π Time and Auxiliary Space Complexity
Expected Time Complexity: O(n Γ mΒ² Γ 4), where n is the number of rows and m is the number of columns. We explore all possible states (i1, j1, j2) and for each state, we try 4 transitions (2 directions for each robot). Each state is computed only once due to memoization.
Expected Auxiliary Space Complexity: O(n Γ mΒ²), as we use a 3D DP table to store memoized results for all possible states of the two robots plus recursion stack space in case of recursive approach.
π§βπ» Code (C++)
class Solution {
public:
int chocolatePickup(vector<vector<int>>& mat) {
int n = mat.size(), m = mat[0].size();
vector<vector<vector<int>>> dp(n, vector<vector<int>>(m, vector<int>(m, -1)));
function<int(int,int,int)> solve = [&](int i1, int j1, int j2) -> int {
int i2 = i1 + j1 - j2;
if (i1 >= n || i2 >= n || j1 >= m || j2 >= m || i2 < 0) return -1e8;
if (mat[i1][j1] == -1 || mat[i2][j2] == -1) return -1e8;
if (i1 == n - 1 && j1 == m - 1 && j2 == m - 1) return mat[i1][j1];
if (dp[i1][j1][j2] != -1) return dp[i1][j1][j2];
int res = -1e8;
for (int d1 = 0; d1 < 2; d1++)
for (int d2 = 0; d2 < 2; d2++)
res = max(res, solve(i1 + 1 - d1, j1 + d1, j2 + d2));
res += mat[i1][j1];
if (i1 != i2) res += mat[i2][j2];
return dp[i1][j1][j2] = res;
};
return max(0, solve(0, 0, 0));
}
};β Code (Java)
class Solution {
int[][][] dp;
int[][] mat;
int n, m;
int solve(int i1, int j1, int j2) {
int i2 = i1 + j1 - j2;
if (i1 >= n || i2 >= n || j1 >= m || j2 >= m || i2 < 0) return (int)-1e8;
if (mat[i1][j1] == -1 || mat[i2][j2] == -1) return (int)-1e8;
if (i1 == n - 1 && j1 == m - 1 && j2 == m - 1) return mat[i1][j1];
if (dp[i1][j1][j2] != -1) return dp[i1][j1][j2];
int res = (int)-1e8;
for (int d1 = 0; d1 < 2; d1++)
for (int d2 = 0; d2 < 2; d2++)
res = Math.max(res, solve(i1 + 1 - d1, j1 + d1, j2 + d2));
res += mat[i1][j1];
if (i1 != i2) res += mat[i2][j2];
return dp[i1][j1][j2] = res;
}
public int chocolatePickup(int[][] mat) {
this.mat = mat;
n = mat.length;
m = mat[0].length;
dp = new int[n][m][m];
for (int[][] a : dp) for (int[] b : a) Arrays.fill(b, -1);
return Math.max(0, solve(0, 0, 0));
}
}π Code (Python)
class Solution:
def chocolatePickup(self, mat):
n, m = len(mat), len(mat[0])
dp = [[[-1] * m for _ in range(m)] for _ in range(n)]
def solve(i1, j1, j2):
i2 = i1 + j1 - j2
if i1 >= n or i2 >= n or j1 >= m or j2 >= m or i2 < 0:
return -10**8
if mat[i1][j1] == -1 or mat[i2][j2] == -1:
return -10**8
if i1 == n - 1 and j1 == m - 1 and j2 == m - 1:
return mat[i1][j1]
if dp[i1][j1][j2] != -1:
return dp[i1][j1][j2]
res = -10**8
for d1 in range(2):
for d2 in range(2):
res = max(res, solve(i1 + 1 - d1, j1 + d1, j2 + d2))
res += mat[i1][j1]
if i1 != i2:
res += mat[i2][j2]
dp[i1][j1][j2] = res
return res
return max(0, solve(0, 0, 0))π§ Contribution and Support
For discussions, questions, or doubts related to this solution, feel free to connect on LinkedIn: π¬ Any Questions?. Let's make this learning journey more collaborative!
β If you find this helpful, please give this repository a star! β
πVisitor Count
Last updated