Maximizing Chocolates in Round Trip(Chocolates Pickup II)
Last Updated : 7 Nov, 2025
You are given an n*n grid mat[][], where each cell represents either:
a blocked cell, denoted by -1, or
a cell containing chocolates, denoted by a non-negative integer mat[i][j], representing the number of chocolates in that cell.
A robot starts at the top-left corner (0, 0) and must travel to the bottom-right corner (n-1, n-1) by moving only right or down at each step. After reaching (n-1, n-1), the robot must return to (0, 0), by moving only left or up.
Note: Each time the robot visits a cell, it collects all chocolates from that cell, and the cell becomes empty(mat[i][j] = 0). Thus, chocolates cannot be collected more than once from the same cell.
Determine the maximum number of chocolates the robot can collect during its complete round trip.
Output: 5 Explanation: The maximum number of chocolates in the round trip can be obtained by moving from (0, 0) -> (1, 0) -> (2, 0) -> (2, 1) -> (2, 2), and then returning back to (0, 0) along the path (2, 2) -> (2, 1) -> (1, 1) -> (0, 1) -> (0, 0).
Output: 7 Explanation: The maximum number of chocolates in the round trip can be obtained by moving from (0, 0) -> (1, 0) -> (2, 0) -> (2, 1) -> (2, 2) and then returning back to (0, 0) along the path(2, 2) -> (1, 2) -> (1, 1) -> (0, 1) -> (0, 0).
Input: mat[][] = [[1, 1, -1], [1, -1, 1], [-1, 1, 1]] Output: 0 Explanation: There is no possible path to reach the bottom right (n-1, n-1) cell hence we cannot collect any chocolate.
If the robot moves from (0, 0) to (n-1, n-1) and then back to (0, 0), some cells will be visited twice. To make sure we don’t count the chocolates in those cells twice, we would need to remember which cells were already visited during the first trip. Doing that would require an extra boolean matrix to track visited cells for every possible path, which would take a lot of extra space and make the solution inefficient.
Instead, we can imagine two robots starting from (0, 0) and moving through the grid simultaneously toward (n−1, n−1). Both robots can move only right or down at each step, and they collect chocolates from the cells they visit. If both robots happen to visit the same cell, it will occur at the same instant, and the chocolates in that cell are counted only once. This way, we naturally ensure that each cell’s chocolates are added at most once, without needing any extra matrix to track visited cells.
[Naive Approach] - Using Recursion – O(4n) Time and O(n) Space
Both robots start at (0, 0) and move toward (n–1, n–1) simultaneously. In each step, both can move either right or down, giving four possible move combinations in total. They collect chocolates from the cells they visit, but if both robots land on the same cell, we count the chocolates there only once. To find the maximum chocolates they can collect together, we explore all possible move combinations at each step and take the one that gives the highest total. This can be solved recursively by trying all four possible moves for both robots and choosing the combination that results in the maximum chocolates.
C++
//Driver Code Starts#include<climits>#include<iostream>#include<vector>usingnamespacestd;//Driver Code EndsintmaxChocolates(inti1,intj1,inti2,intj2,vector<vector<int>>&mat){intn=mat.size();intm=mat[0].size();// check if any of the robots// is outside the gridif(i1>=n||i2>=n||j1>=m||j2>=m)returnINT_MIN;// check if any of the robots is// in a blocked cellif(mat[i1][j1]==-1||mat[i2][j2]==-1)returnINT_MIN;if(i1==n-1&&j1==m-1&&j2==m-1)returnmat[i1][j1];intans=INT_MIN;// a robot can either move downwards or rightwardsintdir[2][2]={{1,0},{0,1}};for(auto&d1:dir){for(auto&d2:dir){intnewRow1=i1+d1[0];intnewCol1=j1+d1[1];intnewRow2=i2+d2[0];intnewCol2=j2+d2[1];// taking maximum chocolates// among all possibilitiesans=max(ans,maxChocolates(newRow1,newCol1,newRow2,newCol2,mat));}}ans+=mat[i1][j1];// if both robots are not in the same cellif(i1!=i2)ans+=mat[i2][j2];returnans;}intchocolatePickup(vector<vector<int>>&mat){intn=mat.size();intm=mat[0].size();returnmax(0,maxChocolates(0,0,0,0,mat));}//Driver Code Startsintmain(){vector<vector<int>>mat={{0,1,-1},{1,1,-1},{1,1,2}};cout<<chocolatePickup(mat);}//Driver Code Ends
Java
//Driver Code Startsimportjava.util.ArrayList;importjava.util.List;classGFG{//Driver Code EndsstaticintchocolatePickup(int[][]mat){intn=mat.length;intm=mat[0].length;returnMath.max(0,maxChocolates(0,0,0,0,mat));}staticintmaxChocolates(inti1,intj1,inti2,intj2,int[][]mat){intn=mat.length;intm=mat[0].length;// check if any of the robots// is outside the gridif(i1>=n||i2>=n||j1>=m||j2>=m)returnInteger.MIN_VALUE;// check if any of the robots is// in a blocked cellif(mat[i1][j1]==-1||mat[i2][j2]==-1)returnInteger.MIN_VALUE;if(i1==n-1&&j1==m-1&&j2==m-1)returnmat[i1][j1];intans=Integer.MIN_VALUE;// a robot can either move downwards or rightwardsint[][]dir={{1,0},{0,1}};for(int[]d1:dir){for(int[]d2:dir){intnewRow1=i1+d1[0];intnewCol1=j1+d1[1];intnewRow2=i2+d2[0];intnewCol2=j2+d2[1];// taking maximum chocolates// among all possibilitiesans=Math.max(ans,maxChocolates(newRow1,newCol1,newRow2,newCol2,mat));}}ans+=mat[i1][j1];// if both robots are not in the same cellif(i1!=i2)ans+=mat[i2][j2];returnans;}//Driver Code Startspublicstaticvoidmain(String[]args){int[][]mat={{0,1,-1},{1,1,-1},{1,1,2}};System.out.println(chocolatePickup(mat));}}//Driver Code Ends
Python
defchocolatePickup(mat):n=len(mat)m=len(mat[0])returnmax(0,maxChocolates(0,0,0,0,mat))defmaxChocolates(i1,j1,i2,j2,mat):n=len(mat)m=len(mat[0])# check if any of the robots# is outside the gridifi1>=nori2>=norj1>=morj2>=m:returnfloat('-inf')# check if any of the robots is# in a blocked cellifmat[i1][j1]==-1ormat[i2][j2]==-1:returnfloat('-inf')ifi1==n-1andj1==m-1andj2==m-1:returnmat[i1][j1]ans=float('-inf')# a robot can either move downwards or rightwardsdir=[[1,0],[0,1]]ford1indir:ford2indir:newRow1=i1+d1[0]newCol1=j1+d1[1]newRow2=i2+d2[0]newCol2=j2+d2[1]# taking maximum chocolates# among all possibilitiesans=max(ans,maxChocolates(newRow1,newCol1,newRow2,newCol2,mat))ans+=mat[i1][j1]# if both robots are not in the same cellifi1!=i2:ans+=mat[i2][j2]returnans#Driver Code Startsif__name__=="__main__":mat=[[0,1,-1],[1,1,-1],[1,1,2]]print(chocolatePickup(mat))#Driver Code Ends
C#
//Driver Code StartsusingSystem;classGFG{//Driver Code EndsstaticintchocolatePickup(int[][]mat){intn=mat.Length;intm=mat[0].Length;returnMath.Max(0,maxChocolates(0,0,0,0,mat));}staticintmaxChocolates(inti1,intj1,inti2,intj2,int[][]mat){intn=mat.Length;intm=mat[0].Length;// check if any of the robots// is outside the gridif(i1>=n||i2>=n||j1>=m||j2>=m)returnint.MinValue;// check if any of the robots is// in a blocked cellif(mat[i1][j1]==-1||mat[i2][j2]==-1)returnint.MinValue;if(i1==n-1&&j1==m-1&&j2==m-1)returnmat[i1][j1];intans=int.MinValue;// a robot can either move downwards or rightwardsint[][]dir=newint[][]{newint[]{1,0},newint[]{0,1}};foreach(int[]d1indir){foreach(int[]d2indir){intnewRow1=i1+d1[0];intnewCol1=j1+d1[1];intnewRow2=i2+d2[0];intnewCol2=j2+d2[1];// taking maximum chocolates// among all possibilitiesans=Math.Max(ans,maxChocolates(newRow1,newCol1,newRow2,newCol2,mat));}}ans+=mat[i1][j1];// if both robots are not in the same cellif(i1!=i2)ans+=mat[i2][j2];returnans;}//Driver Code StartsstaticvoidMain(){int[][]mat={newint[]{0,1,-1},newint[]{1,1,-1},newint[]{1,1,2}};Console.WriteLine(chocolatePickup(mat));}}//Driver Code Ends
JavaScript
functionchocolatePickup(mat){constn=mat.length;constm=mat[0].length;returnMath.max(0,maxChocolates(0,0,0,0,mat));}functionmaxChocolates(i1,j1,i2,j2,mat){constn=mat.length;constm=mat[0].length;// check if any of the robots// is outside the gridif(i1>=n||i2>=n||j1>=m||j2>=m)return-Infinity;// check if any of the robots is// in a blocked cellif(mat[i1][j1]===-1||mat[i2][j2]===-1)return-Infinity;if(i1===n-1&&j1===m-1&&j2===m-1)returnmat[i1][j1];letans=-Infinity;// a robot can either move downwards or rightwardsconstdir=[[1,0],[0,1]];for(constd1ofdir){for(constd2ofdir){constnewRow1=i1+d1[0];constnewCol1=j1+d1[1];constnewRow2=i2+d2[0];constnewCol2=j2+d2[1];// taking maximum chocolates// among all possibilitiesans=Math.max(ans,maxChocolates(newRow1,newCol1,newRow2,newCol2,mat));}}ans+=mat[i1][j1];// if both robots are not in the same cellif(i1!==i2)ans+=mat[i2][j2];returnans;}// Driver code//Driver Code Startsconstmat=[[0,1,-1],[1,1,-1],[1,1,2]];console.log(chocolatePickup(mat));//Driver Code Ends
Output
7
[Better Approach - 1] - Using Memoization – O(n*m2) Time and O(n*m2) Space
In this approach, we notice that many subproblems repeat. For example, to find the maximum chocolates when both robots are at positions (i1, j1) and (i2, j2), we need the results for the next moves — such as (i1+1, j1, i2+1, j2), (i1+1, j1, i2, j2+1), and others. While calculating results for different positions, some of these states are required multiple times. To avoid recomputing the same values, we store the results of already solved states in a DP table and reuse them whenever needed. This helps reduce redundant calculations and makes the solution much more efficient.
As both robots have the same count of total number of moves at any instant, we can calculate the row of the second robot by equating the total number of moves made by both robots. Therefore, we only need 3 states to keep track of the current position of both robots in the grid.
C++
//Driver Code Starts#include<climits>#include<iostream>#include<vector>usingnamespacestd;//Driver Code EndsintmaxChocolates(inti1,intj1,intj2,vector<vector<int>>&mat,vector<vector<vector<int>>>&dp){intn=mat.size();intm=mat[0].size();// calculating row of 2nd robotinti2=i1+j1-j2;// check if any of the robots// is outside the gridif(i1>=n||i2>=n||j1>=m||j2>=m)returnINT_MIN;// check if any of the robots is// in a blocked cellif(mat[i1][j1]==-1||mat[i2][j2]==-1)returnINT_MIN;if(i1==n-1&&j1==m-1&&j2==m-1)returnmat[i1][j1];// if result is already computed// return the stored valueif(dp[i1][j1][j2]!=-1)returndp[i1][j1][j2];intans=INT_MIN;// a robot can either move downwards or rightwardsintdir[2][2]={{1,0},{0,1}};for(auto&d1:dir){for(auto&d2:dir){intnewRow1=i1+d1[0];intnewCol1=j1+d1[1];intnewCol2=j2+d2[1];// taking maximum chocolates// among all possibilitiesans=max(ans,maxChocolates(newRow1,newCol1,newCol2,mat,dp));}}ans+=mat[i1][j1];// if both robots are not in the same cellif(i1!=i2)ans+=mat[i2][j2];returndp[i1][j1][j2]=ans;}intchocolatePickup(vector<vector<int>>&mat){intn=mat.size();intm=mat[0].size();vector<vector<vector<int>>>dp(n,vector<vector<int>>(m,vector<int>(m,-1)));returnmax(0,maxChocolates(0,0,0,mat,dp));}//Driver Code Startsintmain(){vector<vector<int>>mat={{0,1,-1},{1,1,-1},{1,1,2}};cout<<chocolatePickup(mat);}//Driver Code Ends
Java
//Driver Code Startsimportjava.util.ArrayList;importjava.util.Arrays;importjava.util.List;classGFG{//Driver Code EndsstaticintchocolatePickup(int[][]mat){intn=mat.length;intm=mat[0].length;int[][][]dp=newint[n][m][m];// filling dp with invalid valuefor(int[][]rows:dp){for(int[]row:rows)Arrays.fill(row,-1);}returnMath.max(0,maxChocolates(0,0,0,mat,dp));}staticintmaxChocolates(inti1,intj1,intj2,int[][]mat,int[][][]dp){intn=mat.length;intm=mat[0].length;// calculating row of 2nd robotinti2=i1+j1-j2;// check if any of the robots// is outside the gridif(i1>=n||i2>=n||j1>=m||j2>=m)return-1;// check if any of the robots is// in a blocked cellif(mat[i1][j1]==-1||mat[i2][j2]==-1)returnInteger.MIN_VALUE;if(i1==n-1&&j1==m-1&&j2==m-1)returnmat[i1][j1];// if result is already computed// return the stored valueif(dp[i1][j1][j2]!=-1)returndp[i1][j1][j2];intans=Integer.MIN_VALUE;// a robot can either move downwards or rightwardsint[][]dir={{1,0},{0,1}};for(int[]d1:dir){for(int[]d2:dir){intnewRow1=i1+d1[0];intnewCol1=j1+d1[1];intnewCol2=j2+d2[1];// taking maximum chocolates// among all possibilitiesans=Math.max(ans,maxChocolates(newRow1,newCol1,newCol2,mat,dp));}}if(ans==-1||mat[i2][j2]==-1||mat[i1][j1]==-1){dp[i1][j1][j2]=-1;returndp[i1][j1][j2];}ans+=mat[i1][j1];// if both robots are not in the same cellif(i1!=i2)ans+=mat[i2][j2];returndp[i1][j1][j2]=ans;}//Driver Code Startspublicstaticvoidmain(String[]args){int[][]mat={{0,1,-1},{1,1,-1},{1,1,2}};System.out.println(chocolatePickup(mat));}}//Driver Code Ends
Python
defchocolatePickup(mat):n=len(mat)m=len(mat[0])dp=[[[-1for_inrange(m)]for_inrange(m)]for_inrange(n)]returnmax(0,maxChocolates(0,0,0,mat,dp))defmaxChocolates(i1,j1,j2,mat,dp):n=len(mat)m=len(mat[0])# calculating row of 2nd roboti2=i1+j1-j2# check if any of the robots# is outside the gridifi1>=nori2>=norj1>=morj2>=m:returnfloat('-inf')# check if any of the robots is# in a blocked cellifmat[i1][j1]==-1ormat[i2][j2]==-1:returnfloat('-inf')ifi1==n-1andj1==m-1andj2==m-1:returnmat[i1][j1]# if result is already computed# return the stored valueifdp[i1][j1][j2]!=-1:returndp[i1][j1][j2]ans=float('-inf')# a robot can either move downwards or rightwardsdir=[[1,0],[0,1]]ford1indir:ford2indir:newRow1=i1+d1[0]newCol1=j1+d1[1]newCol2=j2+d2[1]# taking maximum chocolates# among all possibilitiesans=max(ans,maxChocolates(newRow1,newCol1,newCol2,mat,dp))ans+=mat[i1][j1]# if both robots are not in the same cellifi1!=i2:ans+=mat[i2][j2]dp[i1][j1][j2]=ansreturnans#Driver Code Startsif__name__=="__main__":mat=[[0,1,-1],[1,1,-1],[1,1,2]]print(chocolatePickup(mat))#Driver Code Ends
C#
//Driver Code StartsusingSystem;classSolution{//Driver Code EndsstaticintchocolatePickup(int[][]mat){intn=mat.Length;intm=mat[0].Length;int[][][]dp=newint[n][][];for(inti=0;i<n;i++){dp[i]=newint[m][];for(intj=0;j<m;j++){dp[i][j]=newint[m];for(intk=0;k<m;k++)dp[i][j][k]=-1;}}returnMath.Max(0,maxChocolates(0,0,0,mat,dp));}staticintmaxChocolates(inti1,intj1,intj2,int[][]mat,int[][][]dp){intn=mat.Length;intm=mat[0].Length;// calculating row of 2nd robotinti2=i1+j1-j2;// check if any of the robots// is outside the gridif(i1>=n||i2>=n||j1>=m||j2>=m)returnint.MinValue;// check if any of the robots is// in a blocked cellif(mat[i1][j1]==-1||mat[i2][j2]==-1)returnint.MinValue;if(i1==n-1&&j1==m-1&&j2==m-1)returnmat[i1][j1];// if result is already computed// return the stored valueif(dp[i1][j1][j2]!=-1)returndp[i1][j1][j2];intans=int.MinValue;// a robot can either move downwards or rightwardsint[][]dir={newint[]{1,0},newint[]{0,1}};foreach(int[]d1indir){foreach(int[]d2indir){intnewRow1=i1+d1[0];intnewCol1=j1+d1[1];intnewCol2=j2+d2[1];// taking maximum chocolates// among all possibilitiesans=Math.Max(ans,maxChocolates(newRow1,newCol1,newCol2,mat,dp));}}ans+=mat[i1][j1];// if both robots are not in the same cellif(i1!=i2)ans+=mat[i2][j2];returndp[i1][j1][j2]=ans;}//Driver Code StartsstaticvoidMain(){int[][]mat={newint[]{0,1,-1},newint[]{1,1,-1},newint[]{1,1,2}};Console.WriteLine(chocolatePickup(mat));}}//Driver Code Ends
JavaScript
functionchocolatePickup(mat){constn=mat.length;constm=mat[0].length;constdp=Array.from({length:n},()=>Array.from({length:m},()=>Array(m).fill(-1)));returnMath.max(0,maxChocolates(0,0,0,mat,dp));}functionmaxChocolates(i1,j1,j2,mat,dp){constn=mat.length;constm=mat[0].length;// calculating row of 2nd robotconsti2=i1+j1-j2;// check if any of the robots// is outside the gridif(i1>=n||i2>=n||j1>=m||j2>=m)return-Infinity;// check if any of the robots is// in a blocked cellif(mat[i1][j1]===-1||mat[i2][j2]===-1)return-Infinity;if(i1===n-1&&j1===m-1&&j2===m-1)returnmat[i1][j1];// if result is already computed// return the stored valueif(dp[i1][j1][j2]!==-1)returndp[i1][j1][j2];letans=-Infinity;// a robot can either move downwards or rightwardsconstdir=[[1,0],[0,1]];for(constd1ofdir){for(constd2ofdir){constnewRow1=i1+d1[0];constnewCol1=j1+d1[1];constnewCol2=j2+d2[1];// taking maximum chocolates// among all possibilitiesans=Math.max(ans,maxChocolates(newRow1,newCol1,newCol2,mat,dp));}}ans+=mat[i1][j1];// if both robots are not in the same cellif(i1!==i2)ans+=mat[i2][j2];return(dp[i1][j1][j2]=ans);}//Driver Code Starts// Driver codeconstmat=[[0,1,-1],[1,1,-1],[1,1,2]];console.log(chocolatePickup(mat));//Driver Code Ends
Output
7
[Better Approach - 2] - Using Tabulation – O(n*m2) Time and O(n*m2) Space
In this approach, we iteratively calculate the answers starting from the smallest subproblems — the bottom-right corner of the grid. The answer for any cell, where the two robots are at positions (i1, j1) and (i2, j2), depends on the results of their next possible moves — either moving right or down. Using the precomputed results from the cells below or to the right, we can efficiently calculate the maximum chocolates the robots can collect for the current positions. We store these results in a DP table and continue this process upward and leftward until we reach the starting cell (0, 0).
Here, dp[i1][j1][j2] stores the maximum number of chocolates that both robots can collect when they are at cells (i1, j1) and (i2, j2) (i2 = i1+j1-j2) respectively, and move toward the destination cell (n-1, m-1).
C++
//Driver Code Starts#include<climits>#include<iostream>#include<vector>usingnamespacestd;//Driver Code EndsintchocolatePickup(vector<vector<int>>&mat){intn=mat.size();intm=mat[0].size();vector<vector<vector<int>>>dp(n,vector<vector<int>>(m,vector<int>(m,0)));// base casedp[n-1][m-1][m-1]=((mat[n-1][m-1]==-1)?-1:mat[n-1][m-1]);// filling dp array in bottom up wayfor(inti1=n-1;i1>=0;i1--){for(intj1=m-1;j1>=0;j1--){for(intj2=m-1;j2>=0;j2--){// base caseif(i1==n-1&&j1==m-1&&j2==m-1)continue;inti2=i1+j1-j2;// robot2 in an invalid rowif(i2>=n||i2<0)continue;intans=-1;intdir[2][2]={{1,0},{0,1}};for(auto&d1:dir){for(auto&d2:dir){intnewRow1=i1+d1[0];intnewCol1=j1+d1[1];intnewRow2=i2+d2[0];intnewCol2=j2+d2[1];// taking maximum chocolates// among all possibilitiesif(newRow1<n&&newRow2<n&&newCol1<m&&newCol2<m&&mat[newRow1][newCol1]!=-1&&mat[newRow2][newCol2]!=-1)ans=max(ans,dp[newRow1][newCol1][newCol2]);}}if(ans==-1||mat[i1][j1]==-1||mat[i2][j2]==-1){dp[i1][j1][j2]=-1;continue;}ans+=mat[i1][j1];// if both robots not in the same cellif(i1!=i2&&mat[i1][j1]!=-1)ans+=mat[i2][j2];dp[i1][j1][j2]=ans;}}}// returning 0 if its not possible(negative value)// else maximum chocolates obtainedreturnmax(0,dp[0][0][0]);}//Driver Code Startsintmain(){vector<vector<int>>mat={{0,1,-1},{1,1,-1},{1,1,2}};cout<<chocolatePickup(mat);}//Driver Code Ends
Java
//Driver Code Startsimportjava.util.ArrayList;importjava.util.Arrays;classGFG{//Driver Code EndsstaticintchocolatePickup(int[][]mat){intn=mat.length;intm=mat[0].length;int[][][]dp=newint[n][m][m];// base casedp[n-1][m-1][m-1]=((mat[n-1][m-1]==-1)?-1:mat[n-1][m-1]);// filling dp array in bottom up wayfor(inti1=n-1;i1>=0;i1--){for(intj1=m-1;j1>=0;j1--){for(intj2=m-1;j2>=0;j2--){// base caseif(i1==n-1&&j1==m-1&&j2==m-1)continue;inti2=i1+j1-j2;// robot2 in an invalid rowif(i2>=n||i2<0)continue;intans=-1;int[][]dir={{1,0},{0,1}};for(int[]d1:dir){for(int[]d2:dir){intnewRow1=i1+d1[0];intnewCol1=j1+d1[1];intnewRow2=i2+d2[0];intnewCol2=j2+d2[1];// taking maximum chocolates// among all possibilitiesif(newRow1<n&&newRow2<n&&newCol1<m&&newCol2<m&&mat[newRow1][newCol1]!=-1&&mat[newRow2][newCol2]!=-1)ans=Math.max(ans,dp[newRow1][newCol1][newCol2]);}}if(ans==-1||mat[i1][j1]==-1||mat[i2][j2]==-1){dp[i1][j1][j2]=-1;continue;}ans+=mat[i1][j1];// if both robots not in the same cellif(i1!=i2&&mat[i1][j1]!=-1)ans+=mat[i2][j2];dp[i1][j1][j2]=ans;}}}// returning 0 if its not possible(negative value)// else maximum chocolates obtainedreturn(int)Math.max(0,dp[0][0][0]);}//Driver Code Startspublicstaticvoidmain(String[]args){int[][]mat={{0,1,-1},{1,1,-1},{1,1,2}};System.out.println(chocolatePickup(mat));}}//Driver Code Ends
Python
defchocolatePickup(mat):n=len(mat)m=len(mat[0])dp=[[[0for_inrange(m)]for_inrange(m)]for_inrange(n)]# base casedp[n-1][m-1][m-1]=(-1ifmat[n-1][m-1]==-1elsemat[n-1][m-1])# filling dp array in bottom up wayfori1inrange(n-1,-1,-1):forj1inrange(m-1,-1,-1):forj2inrange(m-1,-1,-1):# base caseifi1==n-1andj1==m-1andj2==m-1:continuei2=i1+j1-j2# robot2 in an invalid rowifi2>=nori2<0:continueans=-1dir=[[1,0],[0,1]]ford1indir:ford2indir:newRow1=i1+d1[0]newCol1=j1+d1[1]newRow2=i2+d2[0]newCol2=j2+d2[1]# taking maximum chocolates# among all possibilitiesif(newRow1<nandnewRow2<nandnewCol1<mandnewCol2<mandmat[newRow1][newCol1]!=-1andmat[newRow2][newCol2]!=-1):ans=max(ans,dp[newRow1][newCol1][newCol2])ifans==-1ormat[i1][j1]==-1ormat[i2][j2]==-1:dp[i1][j1][j2]=-1continueans+=mat[i1][j1]# if both robots not in the same cellifi1!=i2andmat[i1][j1]!=-1:ans+=mat[i2][j2]dp[i1][j1][j2]=ans# returning 0 if its not possible(negative value)# else maximum chocolates obtainedreturnmax(0,dp[0][0][0])#Driver Code Startsif__name__=="__main__":mat=[[0,1,-1],[1,1,-1],[1,1,2]]print(chocolatePickup(mat))#Driver Code Ends
C#
//Driver Code StartsusingSystem;classGFG{//Driver Code EndsstaticintchocolatePickup(int[][]mat){intn=mat.Length;intm=mat[0].Length;int[,,]dp=newint[n,m,m];// base casedp[n-1,m-1,m-1]=((mat[n-1][m-1]==-1)?-1:mat[n-1][m-1]);// filling dp array in bottom up wayfor(inti1=n-1;i1>=0;i1--){for(intj1=m-1;j1>=0;j1--){for(intj2=m-1;j2>=0;j2--){// base caseif(i1==n-1&&j1==m-1&&j2==m-1)continue;inti2=i1+j1-j2;// robot2 in an invalid rowif(i2>=n||i2<0)continue;intans=-1;int[][]dir=newint[][]{newint[]{1,0},newint[]{0,1}};foreach(vard1indir){foreach(vard2indir){intnewRow1=i1+d1[0];intnewCol1=j1+d1[1];intnewRow2=i2+d2[0];intnewCol2=j2+d2[1];// taking maximum chocolates// among all possibilitiesif(newRow1<n&&newRow2<n&&newCol1<m&&newCol2<m&&mat[newRow1][newCol1]!=-1&&mat[newRow2][newCol2]!=-1)ans=Math.Max(ans,dp[newRow1,newCol1,newCol2]);}}if(ans==-1||mat[i1][j1]==-1||mat[i2][j2]==-1){dp[i1,j1,j2]=-1;continue;}ans+=mat[i1][j1];// if both robots not in the same cellif(i1!=i2&&mat[i1][j1]!=-1)ans+=mat[i2][j2];dp[i1,j1,j2]=ans;}}}// returning 0 if its not possible(negative value)// else maximum chocolates obtainedreturnMath.Max(0,dp[0,0,0]);}//Driver Code StartspublicstaticvoidMain(){int[][]mat={newint[]{0,1,-1},newint[]{1,1,-1},newint[]{1,1,2}};Console.WriteLine(chocolatePickup(mat));}}//Driver Code Ends
JavaScript
functionchocolatePickup(mat){constn=mat.length;constm=mat[0].length;constdp=Array.from({length:n},()=>Array.from({length:m},()=>Array(m).fill(0)));// base casedp[n-1][m-1][m-1]=((mat[n-1][m-1]==-1)?-1:mat[n-1][m-1]);// filling dp array in bottom up wayfor(leti1=n-1;i1>=0;i1--){for(letj1=m-1;j1>=0;j1--){for(letj2=m-1;j2>=0;j2--){// base caseif(i1==n-1&&j1==m-1&&j2==m-1)continue;leti2=i1+j1-j2;// robot2 in an invalid rowif(i2>=n||i2<0)continue;letans=-1;constdir=[[1,0],[0,1]];for(letd1ofdir){for(letd2ofdir){letnewRow1=i1+d1[0];letnewCol1=j1+d1[1];letnewRow2=i2+d2[0];letnewCol2=j2+d2[1];// taking maximum chocolates// among all possibilitiesif(newRow1<n&&newRow2<n&&newCol1<m&&newCol2<m&&mat[newRow1][newCol1]!=-1&&mat[newRow2][newCol2]!=-1)ans=Math.max(ans,dp[newRow1][newCol1][newCol2]);}}if(ans==-1||mat[i1][j1]==-1||mat[i2][j2]==-1){dp[i1][j1][j2]=-1;continue;}ans+=mat[i1][j1];// if both robots not in the same cellif(i1!=i2&&mat[i1][j1]!=-1)ans+=mat[i2][j2];dp[i1][j1][j2]=ans;}}}// returning 0 if its not possible(negative value)// else maximum chocolates obtainedreturnMath.max(0,dp[0][0][0]);}//Driver Code Starts// Driver codeconstmat=[[0,1,-1],[1,1,-1],[1,1,2]];console.log(chocolatePickup(mat));//Driver Code Ends
Output
7
[Expected Approach] - Space Optimized DP – O(n*m2) Time and O(m2) Space
In this approach, we iteratively compute the results for one row at a time instead of maintaining the full 3D DP table. We use two 2D arrays — one for the current row and other for the next row. Starting from the bottom-right corner and moving upward, we calculate the maximum chocolates that both robots can collect for each pair of column positions (j1, j2) in row i1. For each state, we use results from the next row when robots move down and from the current row when they move right, since we process the grid from right to left. After finishing a row, we update next = current and move one row up. This way, curr[j1][j2] at an iteration stores the best possible chocolates for positions (i1, j1) and (i2, j2) (i2 = i1 + j1 - j2) using previously computed results, achieving both time and space efficiency.
C++
//Driver Code Starts#include<climits>#include<iostream>#include<vector>usingnamespacestd;//Driver Code EndsintchocolatePickup(vector<vector<int>>&mat){intn=mat.size();intm=mat[0].size();// for storing the answers for current rowvector<vector<int>>curr(m,vector<int>(m,0));// for storing the answers of next rowvector<vector<int>>next(m,vector<int>(m,0));// filling dp array in bottom up wayfor(inti1=n-1;i1>=0;i1--){// creating a new array to fill answers// for current row based on next rowcurr=vector<vector<int>>(m,vector<int>(m,0));for(intj1=m-1;j1>=0;j1--){for(intj2=m-1;j2>=0;j2--){// base caseif(i1==n-1&&j1==m-1&&j2==m-1){curr[m-1][m-1]=((mat[n-1][m-1]==-1)?-1:mat[n-1][m-1]);continue;}inti2=i1+j1-j2;// robot2 in an invalid rowif(i2>=n||i2<0)continue;intans=-1;intdir[2][2]={{1,0},{0,1}};for(auto&d1:dir){for(auto&d2:dir){intnewRow1=i1+d1[0];intnewCol1=j1+d1[1];intnewRow2=i2+d2[0];intnewCol2=j2+d2[1];// taking maximum chocolates// among all possibilitiesif(newRow1<n&&newRow2<n&&newCol1<m&&newCol2<m&&mat[newRow1][newCol1]!=-1&&mat[newRow2][newCol2]!=-1){if(newRow1==i1+1){ans=max(ans,next[newCol1][newCol2]);}else{ans=max(ans,curr[newCol1][newCol2]);}}}}if(ans==-1||mat[i1][j1]==-1||mat[i2][j2]==-1){curr[j1][j2]=-1;continue;}ans+=mat[i1][j1];// if both robots not in the same cellif(i1!=i2&&mat[i1][j1]!=-1)ans+=mat[i2][j2];curr[j1][j2]=ans;}}next=curr;}// returning 0 if its not possible(negative value)// else maximum chocolates obtainedreturnmax(0,next[0][0]);}//Driver Code Startsintmain(){vector<vector<int>>mat={{0,1,-1},{1,1,-1},{1,1,2}};cout<<chocolatePickup(mat);}//Driver Code Ends
Java
//Driver Code Startsimportjava.util.ArrayList;importjava.util.Arrays;classGFG{//Driver Code EndsstaticintchocolatePickup(int[][]mat){intn=mat.length;intm=mat[0].length;// for storing the answers for current rowint[][]curr=newint[m][m];// for storing the answers of next rowint[][]next=newint[m][m];// filling dp array in bottom up wayfor(inti1=n-1;i1>=0;i1--){// creating a new array to fill answers// for current row based on next rowcurr=newint[m][m];for(intj1=m-1;j1>=0;j1--){for(intj2=m-1;j2>=0;j2--){// base caseif(i1==n-1&&j1==m-1&&j2==m-1){curr[m-1][m-1]=((mat[n-1][m-1]==-1)?-1:mat[n-1][m-1]);continue;}inti2=i1+j1-j2;// robot2 in an invalid rowif(i2>=n||i2<0)continue;intans=-1;int[][]dir={{1,0},{0,1}};for(int[]d1:dir){for(int[]d2:dir){intnewRow1=i1+d1[0];intnewCol1=j1+d1[1];intnewRow2=i2+d2[0];intnewCol2=j2+d2[1];// taking maximum chocolates// among all possibilitiesif(newRow1<n&&newRow2<n&&newCol1<m&&newCol2<m&&mat[newRow1][newCol1]!=-1&&mat[newRow2][newCol2]!=-1){if(newRow1==i1+1){ans=Math.max(ans,next[newCol1][newCol2]);}else{ans=Math.max(ans,curr[newCol1][newCol2]);}}}}if(ans==-1||mat[i1][j1]==-1||mat[i2][j2]==-1){curr[j1][j2]=-1;continue;}ans+=mat[i1][j1];// if both robots not in the same cellif(i1!=i2&&mat[i1][j1]!=-1)ans+=mat[i2][j2];curr[j1][j2]=ans;}}next=curr;}// returning 0 if its not possible(negative value)// else maximum chocolates obtainedreturn(int)Math.max(0,next[0][0]);}//Driver Code Startspublicstaticvoidmain(String[]args){int[][]mat={{0,1,-1},{1,1,-1},{1,1,2}};System.out.println(chocolatePickup(mat));}}//Driver Code Ends
Python
defchocolatePickup(mat):n=len(mat)m=len(mat[0])# for storing the answers for current rowcurr=[[0]*mfor_inrange(m)]# for storing the answers of next rownext=[[0]*mfor_inrange(m)]# filling dp array in bottom up wayfori1inrange(n-1,-1,-1):# creating a new array to fill answers# for current row based on next rowcurr=[[0]*mfor_inrange(m)]forj1inrange(m-1,-1,-1):forj2inrange(m-1,-1,-1):# base caseifi1==n-1andj1==m-1andj2==m-1:curr[m-1][m-1]=(-1ifmat[n-1][m-1]==-1elsemat[n-1][m-1])continuei2=i1+j1-j2# robot2 in an invalid rowifi2>=nori2<0:continueans=-1dir=[[1,0],[0,1]]ford1indir:ford2indir:newRow1=i1+d1[0]newCol1=j1+d1[1]newRow2=i2+d2[0]newCol2=j2+d2[1]# taking maximum chocolates# among all possibilitiesif(newRow1<nandnewRow2<nandnewCol1<mandnewCol2<mandmat[newRow1][newCol1]!=-1andmat[newRow2][newCol2]!=-1):ifnewRow1==i1+1:ans=max(ans,next[newCol1][newCol2])else:ans=max(ans,curr[newCol1][newCol2])ifans==-1ormat[i1][j1]==-1ormat[i2][j2]==-1:curr[j1][j2]=-1continueans+=mat[i1][j1]# if both robots not in the same cellifi1!=i2andmat[i1][j1]!=-1:ans+=mat[i2][j2]curr[j1][j2]=ansnext=curr# returning 0 if its not possible(negative value)# else maximum chocolates obtainedreturnmax(0,next[0][0])#Driver Code Startsif__name__=="__main__":mat=[[0,1,-1],[1,1,-1],[1,1,2]]print(chocolatePickup(mat))#Driver Code Ends
C#
//Driver Code StartsusingSystem;classGFG{//Driver Code EndsstaticintchocolatePickup(int[][]mat){intn=mat.Length;intm=mat[0].Length;// for storing the answers for current rowint[][]curr=newint[m][];// for storing the answers of next rowint[][]next=newint[m][];for(inti=0;i<m;i++)next[i]=newint[m];// filling dp array in bottom up wayfor(inti1=n-1;i1>=0;i1--){// creating a new array to fill answers// for current row based on next rowcurr=newint[m][];for(inti=0;i<m;i++)curr[i]=newint[m];for(intj1=m-1;j1>=0;j1--){for(intj2=m-1;j2>=0;j2--){// base caseif(i1==n-1&&j1==m-1&&j2==m-1){curr[m-1][m-1]=((mat[n-1][m-1]==-1)?-1:mat[n-1][m-1]);continue;}inti2=i1+j1-j2;// robot2 in an invalid rowif(i2>=n||i2<0)continue;intans=-1;int[][]dir=newint[][]{newint[]{1,0},newint[]{0,1}};foreach(vard1indir){foreach(vard2indir){intnewRow1=i1+d1[0];intnewCol1=j1+d1[1];intnewRow2=i2+d2[0];intnewCol2=j2+d2[1];// taking maximum chocolates// among all possibilitiesif(newRow1<n&&newRow2<n&&newCol1<m&&newCol2<m&&mat[newRow1][newCol1]!=-1&&mat[newRow2][newCol2]!=-1){if(newRow1==i1+1){ans=Math.Max(ans,next[newCol1][newCol2]);}else{ans=Math.Max(ans,curr[newCol1][newCol2]);}}}}if(ans==-1||mat[i1][j1]==-1||mat[i2][j2]==-1){curr[j1][j2]=-1;continue;}ans+=mat[i1][j1];// if both robots not in the same cellif(i1!=i2&&mat[i1][j1]!=-1)ans+=mat[i2][j2];curr[j1][j2]=ans;}}next=curr;}// returning 0 if its not possible(negative value)// else maximum chocolates obtainedreturnMath.Max(0,next[0][0]);}//Driver Code StartspublicstaticvoidMain(){int[][]mat={newint[]{0,1,-1},newint[]{1,1,-1},newint[]{1,1,2}};Console.WriteLine(chocolatePickup(mat));}}//Driver Code Ends
JavaScript
functionchocolatePickup(mat){constn=mat.length;constm=mat[0].length;// for storing the answers for current rowletcurr=Array.from({length:m},()=>Array(m).fill(0));// for storing the answers of next rowletnext=Array.from({length:m},()=>Array(m).fill(0));// filling dp array in bottom up wayfor(leti1=n-1;i1>=0;i1--){// creating a new array to fill answers// for current row based on next rowcurr=Array.from({length:m},()=>Array(m).fill(0));for(letj1=m-1;j1>=0;j1--){for(letj2=m-1;j2>=0;j2--){// base caseif(i1==n-1&&j1==m-1&&j2==m-1){curr[m-1][m-1]=(mat[n-1][m-1]==-1?-1:mat[n-1][m-1]);continue;}leti2=i1+j1-j2;// robot2 in an invalid rowif(i2>=n||i2<0)continue;letans=-1;constdir=[[1,0],[0,1]];for(constd1ofdir){for(constd2ofdir){letnewRow1=i1+d1[0];letnewCol1=j1+d1[1];letnewRow2=i2+d2[0];letnewCol2=j2+d2[1];// taking maximum chocolates// among all possibilitiesif(newRow1<n&&newRow2<n&&newCol1<m&&newCol2<m&&mat[newRow1][newCol1]!=-1&&mat[newRow2][newCol2]!=-1){if(newRow1==i1+1){ans=Math.max(ans,next[newCol1][newCol2]);}else{ans=Math.max(ans,curr[newCol1][newCol2]);}}}}if(ans==-1||mat[i1][j1]==-1||mat[i2][j2]==-1){curr[j1][j2]=-1;continue;}ans+=mat[i1][j1];// if both robots not in the same cellif(i1!=i2&&mat[i1][j1]!=-1)ans+=mat[i2][j2];curr[j1][j2]=ans;}}next=curr;}// returning 0 if its not possible(negative value)// else maximum chocolates obtainedreturnMath.max(0,next[0][0]);}// Driver codeconstmat=[[0,1,-1],[1,1,-1],[1,1,2]];console.log(chocolatePickup(mat));