# Maximum points by traversing from top left of Matrix to bottom right by two persons

• Last Updated : 08 Oct, 2021

Given a matrix grid[][] of order N*M with numbers 0-9 in the cells. The task is to find the maximum amount of money collected when two persons move from (0, 0) to (N-1, M-1) by moving only right and down. If both persons are at the same cell, then only one of them can pick the money at that location.

Examples:

Attention reader! Don’t stop learning now. Get hold of all the important DSA concepts with the DSA Self Paced Course at a student-friendly price and become industry ready.  To complete your preparation from learning a language to DS Algo and many more,  please refer Complete Interview Preparation Course.

In case you wish to attend live classes with experts, please refer DSA Live Classes for Working Professionals and Competitive Programming Live for Students.

Input:
1 1 1
1 0 1
1 1 1
Output: 8
Explanation: Let 1 denote the places where person 1 collects the money and 2 denote where person 2 does so, then a possible solution is
1 1 1
2 0 1
2 2 1

Input:
0 9 9 3 3
2 9 3 3 3
0 3 3 3 3
4 1 1 1 1
Output: 52

Approach: The problem can be solved by using the recursion, by moving both the persons down and right in each of the cell and finding the maximum path sum in all the paths from (0, 0) to (N-1, M-1). So the idea is to find the cost of all possible paths and to find the maximum of them.

Below is the implementation of the above approach:

## C++

 `// C++ program for the above approach``#include ``using` `namespace` `std;` `const` `static` `int` `MAXR = 20, MAXC = 20;``int` `cache[MAXC][MAXR][MAXC][MAXR],``    ``dp[MAXC][MAXR][MAXC][MAXR];``int` `n, m;``vector grid;` `// Function to find maximum money collected``// when moving from (0, 0) to (N-1, M-1)``int` `maxMoney(``int` `x1, ``int` `y1, ``int` `x2, ``int` `y2)``{``    ``// Out of bounds of grid``    ``if` `(x1 >= n || y1 >= m || x2 >= n || y2 >= m)``        ``return` `0;``    ``if` `(cache[x1][y1][x2][y2] != 0)``        ``return` `dp[x1][y1][x2][y2];` `    ``// Mark state as visited``    ``cache[x1][y1][x2][y2] = 1;` `    ``// Collect money from the grid cell``    ``int` `money = grid[y1][x1] - ``'0'``;``    ``if` `(x1 != x2 || y1 != y2)``        ``money += grid[y2][x2] - ``'0'``;` `    ``// Take maximum of all possibilities``    ``return` `dp[x1][y1][x2][y2]``           ``= money``             ``+ max(``                   ``max(maxMoney(x1 + 1, y1, x2 + 1, y2),``                       ``maxMoney(x1, y1 + 1, x2 + 1, y2)),``                   ``max(maxMoney(x1 + 1, y1, x2, y2 + 1),``                       ``maxMoney(x1, y1 + 1, x2, y2 + 1)));``}` `// Driver Code``int32_t main()``{``    ``// Given Input``    ``n = 3;``    ``m = 3;``    ``grid.push_back(``"111"``);``    ``grid.push_back(``"101"``);``    ``grid.push_back(``"111"``);` `    ``// Function Call``    ``cout << maxMoney(0, 0, 0, 0);` `    ``return` `0;``}`

## Java

 `// Java program for the above approach``import` `java.util.*;` `class` `GFG{` `static` `int` `MAXR = ``20``, MAXC = ``20``;``static` `int` `[][][][]cache = ``new` `int``[MAXC][MAXR][MAXC][MAXR];``static` `int` `[][][][]dp = ``new` `int``[MAXC][MAXR][MAXC][MAXR];``static` `int` `n, m;``static` `Vector grid = ``new` `Vector();` `// Function to find maximum money collected``// when moving from (0, 0) to (N-1, M-1)``static` `int` `maxMoney(``int` `x1, ``int` `y1, ``int` `x2, ``int` `y2)``{``    ``// Out of bounds of grid``    ``if` `(x1 >= n || y1 >= m || x2 >= n || y2 >= m)``        ``return` `0``;``    ``if` `(cache[x1][y1][x2][y2] != ``0``)``        ``return` `dp[x1][y1][x2][y2];` `    ``// Mark state as visited``    ``cache[x1][y1][x2][y2] = ``1``;` `    ``// Collect money from the grid cell``    ``int` `money = grid.get(y1).charAt(x1)- ``'0'``;``    ``if` `(x1 != x2 || y1 != y2)``        ``money += grid.get(y2).charAt(x2) - ``'0'``;` `    ``// Take maximum of all possibilities``    ``return` `dp[x1][y1][x2][y2]``           ``= money``             ``+ Math.max(``                   ``Math.max(maxMoney(x1 + ``1``, y1, x2 + ``1``, y2),``                       ``maxMoney(x1, y1 + ``1``, x2 + ``1``, y2)),``                   ``Math.max(maxMoney(x1 + ``1``, y1, x2, y2 + ``1``),``                       ``maxMoney(x1, y1 + ``1``, x2, y2 + ``1``)));``}` `// Driver Code``public` `static` `void` `main(String[] args)``{``  ` `    ``// Given Input``    ``n = ``3``;``    ``m = ``3``;``    ``grid.add(``"111"``);``    ``grid.add(``"101"``);``    ``grid.add(``"111"``);` `    ``// Function Call``    ``System.out.print(maxMoney(``0``, ``0``, ``0``, ``0``));` `}``}` `// This code is contributed by Princi Singh`

## Python3

 `# Python3 program for the above approach``MAXR, MAXC ``=` `20``, ``20` `cache  ``=` `[[[[``0` `for` `i ``in` `range``(MAXR)] ``for` `j ``in` `range``(MAXC)] ``for` `k ``in` `range``(MAXR)] ``for` `l ``in` `range``(MAXC)]``dp  ``=` `[[[[``0` `for` `i ``in` `range``(MAXR)] ``for` `j ``in` `range``(MAXC)] ``for` `k ``in` `range``(MAXR)] ``for` `l ``in` `range``(MAXC)]` `grid ``=` `[]` `# Function to find maximum money collected``# when moving from (0, 0) to (N-1, M-1)``def` `maxMoney(x1, y1, x2, y2):``    ``# Out of bounds of grid``    ``if` `(x1 >``=` `n ``or` `y1 >``=` `m ``or` `x2 >``=` `n ``or` `y2 >``=` `m):``        ``return` `0``    ``if` `(cache[x1][y1][x2][y2] !``=` `0``):``        ``return` `dp[x1][y1][x2][y2]`` ` `    ``# Mark state as visited``    ``cache[x1][y1][x2][y2] ``=` `1`` ` `    ``# Collect money from the grid cell``    ``money ``=` `ord``(grid[y1][x1]) ``-` `ord``(``'0'``)``    ``if` `(x1 !``=` `x2 ``or` `y1 !``=` `y2):``        ``money ``+``=` `ord``(grid[y2][x2]) ``-` `ord``(``'0'``)``    ` `    ``dp[x1][y1][x2][y2] ``=` `money ``+` `max``(``max``(maxMoney(x1 ``+` `1``, y1, x2 ``+` `1``, y2),  maxMoney(x1, y1 ``+` `1``, x2 ``+` `1``, y2)),``                   ``max``(maxMoney(x1 ``+` `1``, y1, x2, y2 ``+` `1``),``                       ``maxMoney(x1, y1 ``+` `1``, x2, y2 ``+` `1``)))`` ` `    ``# Take maximum of all possibilities``    ``return` `dp[x1][y1][x2][y2]` `# Given Input``n ``=` `3``m ``=` `3``grid.append(``"111"``)``grid.append(``"101"``)``grid.append(``"111"``)` `# Function Call``print``(maxMoney(``0``, ``0``, ``0``, ``0``))` `# This code is contributed by suresh07.`

## C#

 `// C# program for the above approach``using` `System;``using` `System.Collections.Generic;` `public` `class` `GFG{` `static` `int` `MAXR = 20, MAXC = 20;``static` `int` `[,,,]cache = ``new` `int``[MAXC,MAXR,MAXC,MAXR];``static` `int` `[,,,]dp = ``new` `int``[MAXC,MAXR,MAXC,MAXR];``static` `int` `n, m;``static` `List grid = ``new` `List();` `// Function to find maximum money collected``// when moving from (0, 0) to (N-1, M-1)``static` `int` `maxMoney(``int` `x1, ``int` `y1, ``int` `x2, ``int` `y2)``{``  ` `    ``// Out of bounds of grid``    ``if` `(x1 >= n || y1 >= m || x2 >= n || y2 >= m)``        ``return` `0;``    ``if` `(cache[x1,y1,x2,y2] != 0)``        ``return` `dp[x1,y1,x2,y2];` `    ``// Mark state as visited``    ``cache[x1,y1,x2,y2] = 1;` `    ``// Collect money from the grid cell``    ``int` `money = grid[y1][x1]- ``'0'``;``    ``if` `(x1 != x2 || y1 != y2)``        ``money += grid[y2][x2] - ``'0'``;` `    ``// Take maximum of all possibilities``    ``return` `dp[x1,y1,x2,y2]``           ``= money``             ``+ Math.Max(``                   ``Math.Max(maxMoney(x1 + 1, y1, x2 + 1, y2),``                       ``maxMoney(x1, y1 + 1, x2 + 1, y2)),``                   ``Math.Max(maxMoney(x1 + 1, y1, x2, y2 + 1),``                       ``maxMoney(x1, y1 + 1, x2, y2 + 1)));``}` `// Driver Code``public` `static` `void` `Main(String[] args)``{``  ` `    ``// Given Input``    ``n = 3;``    ``m = 3;``    ``grid.Add(``"111"``);``    ``grid.Add(``"101"``);``    ``grid.Add(``"111"``);` `    ``// Function Call``    ``Console.Write(maxMoney(0, 0, 0, 0));` `}``}` `// This code is contributed by shikhasingrajput`

## Javascript

 ``
Output
`8`

Time Complexity: O(2N*2M)
Auxiliary Space: O((N*M)2)

My Personal Notes arrow_drop_up