Collect maximum points in a grid using two traversals – GeeksforGeeks

Given a matrix where every cell represents points. How to collect utmost points using two traversals under following conditions ?
Let the dimensions of given grid be R x C.
1 ) The first traversal starts from top leave corner, i.e., ( 0, 0 ) and should reach left bottomland corner, i.e., ( R-1, 0 ). The second traversal starts from crown right corner, i.e., ( 0, C-1 ) and should reach bottom right corner, i.e., ( R-1, C-1 ) /
2 ) From a luff ( iodine, j ), we can move to ( i+1, j+1 ) or ( i+1, j-1 ) or ( i+1, j )
3 ) A traversal gets all points of a especial cell through which it passes. If one traversal has already collected points of a cell, then the other traversal gets no points if goes through that cell again.

Input :
    int arr[R][C] = {{3, 6, 8, 2},
                     {5, 2, 4, 3},
                     {1, 1, 20, 10},
                     {1, 1, 20, 10},
                     {1, 1, 20, 10},
                    };

     Output: 73

Explanation :

First traversal collects total points of value 3 + 2 + 20 + 1 + 1 = 27

Second traversal collects total points of value 2 + 4 + 10 + 20 + 10 = 46.
Total Points collected = 27 + 46 = 73.

We strongly recommend you to minimize your browser and try this yourself first.
The idea is to do both traversals concurrently. We start first from ( 0, 0 ) and second traversal from ( 0, C-1 ) simultaneously. The important thing to note is, at any particular step both traversals will be in same row as in all potential three moves, row number is increased. Let ( x1, y1 ) and ( x2, y2 ) denote current positions of first and second base traversals respectively. frankincense at any clock time x1 will be equal to x2 as both of them move forward but variation is possible along y. Since variation in y could occur in 3 ways no switch ( yttrium ), go left ( y – 1 ), go good ( y + 1 ). so in full 9 combinations among y1, y2 are possible. The 9 cases as mentioned below after base cases.

Both traversals always move forward along x
Base Cases:
// If destinations reached
if (x == R-1 && y1 == 0 && y2 == C-1)
maxPoints(arr, x, y1, y2) = arr[x][y1] + arr[x][y2];

// If any of the two locations is invalid (going out of grid)
if input is not valid
maxPoints(arr, x, y1, y2) = -INF  (minus infinite)

// If both traversals are at same cell, then we count the value of cell
// only once.
If y1 and y2 are same
    result = arr[x][y1]
Else
    result = arr[x][y1] + arr[x][y2] 

result  +=  max { // Max of 9 cases
                  maxPoints(arr, x+1, y1+1, y2),    
                  maxPoints(arr, x+1, y1+1, y2+1),
                  maxPoints(arr, x+1, y1+1, y2-1),
                  maxPoints(arr, x+1, y1-1, y2),    
                  maxPoints(arr, x+1, y1-1, y2+1),
                  maxPoints(arr, x+1, y1-1, y2-1),
                  maxPoints(arr, x+1, y1, y2),
                  maxPoints(arr, x+1, y1, y2+1),
                  maxPoints(arr, x+1, y1, y2-1) 
                }

The above recursive solution has many subproblems that are solved again and again. consequently, we can use Dynamic Programming to solve the above problem more efficiently. Below is memoization ( Memoization is option to table based iterative solution in Dynamic Programming ) based implementation. In below execution, we use a memoization table ‘ mem ’ to keep track of already solved problems.

C++




#include using namespace std; #define R 5 #define C 4 bool isValid( int x, int y1, int y2) {      return (x >= 0 && x < R && y1 >=0 &&              y1 < C && y2 >=0 && y2 < C); } int getMaxUtil( int arr[R][C], int mem[R][C][C], int x, int y1, int y2) {                if (!isValid(x, y1, y2)) return INT_MIN;           if (x == R-1 && y1 == 0 && y2 == C-1)         return (y1 == y2)? arr[x][y1]: arr[x][y1] + arr[x][y2];           if (x == R-1) return INT_MIN;           if (mem[x][y1][y2] != -1) return mem[x][y1][y2];           int ans = INT_MIN;           int temp = (y1 == y2)? arr[x][y1]: arr[x][y1] + arr[x][y2];                   ans = max(ans, temp + getMaxUtil(arr, mem, x+1, y1, y2-1));      ans = max(ans, temp + getMaxUtil(arr, mem, x+1, y1, y2+1));      ans = max(ans, temp + getMaxUtil(arr, mem, x+1, y1, y2));      ans = max(ans, temp + getMaxUtil(arr, mem, x+1, y1-1, y2));      ans = max(ans, temp + getMaxUtil(arr, mem, x+1, y1-1, y2-1));      ans = max(ans, temp + getMaxUtil(arr, mem, x+1, y1-1, y2+1));      ans = max(ans, temp + getMaxUtil(arr, mem, x+1, y1+1, y2));      ans = max(ans, temp + getMaxUtil(arr, mem, x+1, y1+1, y2-1));      ans = max(ans, temp + getMaxUtil(arr, mem, x+1, y1+1, y2+1));      return (mem[x][y1][y2] = ans); } int geMaxCollection( int arr[R][C]) {           int mem[R][C][C];      memset (mem, -1, sizeof (mem));                return getMaxUtil(arr, mem, 0, 0, C-1); } int main() {      int arr[R][C] = {{3, 6, 8, 2},                       {5, 2, 4, 3},                       {1, 1, 20, 10},                       {1, 1, 20, 10},                       {1, 1, 20, 10},                      };      cout << "Maximum collection is " << geMaxCollection(arr);      return 0; }



Java




class GFG {      static final int R = 5 ; static final int C = 4 ; static boolean isValid( int x, int y1, int y2) {      return (x >= 0 && x < R && y1 >= 0 &&              y1 < C && y2 >= 0 && y2 < C); } static int getMaxUtil( int arr[][], int mem[][][],                          int x, int y1, int y2) {                if (!isValid(x, y1, y2)) return Integer.MIN_VALUE;           if (x == R- 1 && y1 == 0 && y2 == C- 1 )      return (y1 == y2)? arr[x][y1]: arr[x][y1] + arr[x][y2];                if (x == R- 1 ) return Integer.MIN_VALUE;           if (mem[x][y1][y2] != - 1 ) return mem[x][y1][y2];           int ans = Integer.MIN_VALUE;                int temp = (y1 == y2)? arr[x][y1]:                  arr[x][y1] + arr[x][y2];                ans = Math.max(ans, temp +              getMaxUtil(arr, mem, x+ 1 , y1, y2- 1 ));      ans = Math.max(ans, temp +              getMaxUtil(arr, mem, x+ 1 , y1, y2+ 1 ));      ans = Math.max(ans, temp +              getMaxUtil(arr, mem, x+ 1 , y1, y2));      ans = Math.max(ans, temp +              getMaxUtil(arr, mem, x+ 1 , y1- 1 , y2));      ans = Math.max(ans, temp +              getMaxUtil(arr, mem, x+ 1 , y1- 1 , y2- 1 ));      ans = Math.max(ans, temp +              getMaxUtil(arr, mem, x+ 1 , y1- 1 , y2+ 1 ));      ans = Math.max(ans, temp +              getMaxUtil(arr, mem, x+ 1 , y1+ 1 , y2));      ans = Math.max(ans, temp +              getMaxUtil(arr, mem, x+ 1 , y1+ 1 , y2- 1 ));      ans = Math.max(ans, temp +              getMaxUtil(arr, mem, x+ 1 , y1+ 1 , y2+ 1 ));      return (mem[x][y1][y2] = ans); } static int geMaxCollection( int arr[][]) {                int [][][]mem = new int [R][C][C];      for ( int i = 0 ; i < R; i++)      {          for ( int j = 0 ; j < C; j++)          {              for ( int l = 0 ; l < C; l++)              mem[i][j][l]=- 1 ;          }      }                return getMaxUtil(arr, mem, 0 , 0 , C- 1 ); } public static void main(String[] args) {      int arr[][] = {{ 3 , 6 , 8 , 2 },                      { 5 , 2 , 4 , 3 },                      { 1 , 1 , 20 , 10 },                      { 1 , 1 , 20 , 10 },                      { 1 , 1 , 20 , 10 },                      };      System.out.print( "Maximum collection is " +                              geMaxCollection(arr));      } }



Python3




R = 5 C = 4 intmin = - 10000000 intmax = 10000000

def isValid(x,y1,y2):      return ((x > = 0 and x < R and y1 > = 0              and y1 < C and y2 > = 0 and y2 < C)) def getMaxUtil(arr,mem,x,y1,y2):           if isValid(x, y1, y2) = = False :          return intmin                    if x = = R - 1 and y1 = = 0 and y2 = = C - 1 :          if y1 = = y2:              return arr[x][y1]          else :              return arr[x][y1] + arr[x][y2]                             if x = = R - 1 :          return intmin                    if mem[x][y1][y2] ! = - 1 :          return mem[x][y1][y2]                    ans = intmin           temp = 0      if y1 = = y2:          temp = arr[x][y1]      else :          temp = arr[x][y1] + arr[x][y2]                         ans = max (ans, temp + getMaxUtil(arr, mem, x + 1 , y1, y2 - 1 ))      ans = max (ans, temp + getMaxUtil(arr, mem, x + 1 , y1, y2 + 1 ))      ans = max (ans, temp + getMaxUtil(arr, mem, x + 1 , y1, y2))      ans = max (ans, temp + getMaxUtil(arr, mem, x + 1 , y1 - 1 , y2))      ans = max (ans, temp + getMaxUtil(arr, mem, x + 1 , y1 - 1 , y2 - 1 ))      ans = max (ans, temp + getMaxUtil(arr, mem, x + 1 , y1 - 1 , y2 + 1 ))      ans = max (ans, temp + getMaxUtil(arr, mem, x + 1 , y1 + 1 , y2))      ans = max (ans, temp + getMaxUtil(arr, mem, x + 1 , y1 + 1 , y2 - 1 ))      ans = max (ans, temp + getMaxUtil(arr, mem, x + 1 , y1 + 1 , y2 + 1 ))      mem[x][y1][y2] = ans      return ans def geMaxCollection(arr):                     mem = [[[ - 1 for i in range (C)] for i in range (C)] for i in range (R)]                          return getMaxUtil(arr, mem, 0 , 0 , C - 1 ) if __name__ = = '__main__' :      arr = [[ 3 , 6 , 8 , 2 ],          [ 5 , 2 , 4 , 3 ],          [ 1 , 1 , 20 , 10 ],          [ 1 , 1 , 20 , 10 ],          [ 1 , 1 , 20 , 10 ],          ]      print ( 'Maximum collection is ' , geMaxCollection(arr))     



C#




using System; class GFG {      static readonly int R = 5; static readonly int C = 4; static bool isValid( int x, int y1, int y2) {      return (x >= 0 && x < R && y1 >=0 &&              y1 < C && y2 >=0 && y2 < C); } static int getMaxUtil( int [,]arr, int [,,]mem,                          int x, int y1, int y2) {                if (!isValid(x, y1, y2)) return int .MinValue;           if (x == R-1 && y1 == 0 && y2 == C-1)      return (y1 == y2)? arr[x, y1]: arr[x, y1] + arr[x, y2];                if (x == R-1) return int .MinValue;           if (mem[x, y1, y2] != -1) return mem[x, y1, y2];           int ans = int .MinValue;                int temp = (y1 == y2)? arr[x, y1]:                  arr[x, y1] + arr[x, y2];                ans = Math.Max(ans, temp +              getMaxUtil(arr, mem, x+1, y1, y2-1));      ans = Math.Max(ans, temp +              getMaxUtil(arr, mem, x+1, y1, y2+1));      ans = Math.Max(ans, temp +              getMaxUtil(arr, mem, x+1, y1, y2));      ans = Math.Max(ans, temp +              getMaxUtil(arr, mem, x+1, y1-1, y2));      ans = Math.Max(ans, temp +              getMaxUtil(arr, mem, x+1, y1-1, y2-1));      ans = Math.Max(ans, temp +              getMaxUtil(arr, mem, x+1, y1-1, y2+1));      ans = Math.Max(ans, temp +              getMaxUtil(arr, mem, x+1, y1+1, y2));      ans = Math.Max(ans, temp +              getMaxUtil(arr, mem, x+1, y1+1, y2-1));      ans = Math.Max(ans, temp +              getMaxUtil(arr, mem, x+1, y1+1, y2+1));      return (mem[x, y1, y2] = ans); } static int geMaxCollection( int [,]arr) {                int [,,]mem = new int [R, C, C];      for ( int i = 0; i < R; i++)      {          for ( int j = 0; j < C; j++)          {              for ( int l = 0; l < C; l++)              mem[i, j, l]=-1;          }      }                return getMaxUtil(arr, mem, 0, 0, C-1); } public static void Main(String[] args) {      int [,]arr = {{3, 6, 8, 2},                      {5, 2, 4, 3},                      {1, 1, 20, 10},                      {1, 1, 20, 10},                      {1, 1, 20, 10},                      };      Console.Write( "Maximum collection is " +                              geMaxCollection(arr));      } }



Javascript






Output: 

Maximum collection is 73

Thanks to Gaurav Ahirwar for suggesting above problem and solution.
Please write comments if you find anything incorrect, or you want to contribution more information about the subject discussed above.

My Personal Notes

Read more: Possum Magic Coins

arrow_drop_up

reference : https://coinselected.com
Category : Coin collecting

Leave a Reply

Your email address will not be published.