Collect maximum points in a grid using two traversals

Dynamic ProgrammingAlgorithmsData Structure

There is a matrix with points in each cell, how to get maximum points from that grid using two traversals.

There is some condition to satisfy:

  1. The first traversal starts from the top left cell in the grid and should go to the bottom left corner.      And in the second traversal starting from top right corner to bottom right corner
  2. From one cell we can only move to bottom, bottom left of the current cell and bottom right of the current cells only.
  3. If one traversal already gets some points from a cell, In the next traversal no points will be gained from that cell.

Input and Output

Input:
A grid with points.
3 6  8  2
5 2  4  3
1 1 20 10
1 1 20 10
1 1 20 10

Output:
Maximum points collected by two traversals is 73.
From the first traversal, it gains: 3 + 2 + 20 + 1 + 1 = 27
From the second traversal, it gains: 2 + 4 + 10 + 20 + 10 = 46

Algorithm

findMaxVal(mTable, x, y1, y2)

Input: a 3D array as memorization table, the x value and y1, y2.

Output: maximum value.

Begin
   if x, y1 and y2 is not valid, then
      return - ∞
   if both traversal is complete, then
      if y1 = y2, then
         return grid[x, y1]
      else
         return grid[x, y1] + grid[x, y2]
   if both traversal are at last row, then
      return - ∞
   if subProblem is solved, then
      return mTable[x, y1, y2]
   set res := - ∞

   if y1 = y2, then
      temp := grid[x, y1]
   else
      temp := grid[x, y1] + grid[x, y2]

   res := max of res and (temp + findMaxVal(mTable, x+1, y1, y2-1))
   res := max of res and (temp + findMaxVal(mTable, x+1, y1, y2+1))
   res := max of res and (temp + findMaxVal(mTable, x+1, y1, y2))
   res := max of res and (temp + findMaxVal(mTable, x+1, y1-1, y2))
   res := max of res and (temp + findMaxVal(mTable, x+1, y1-1, y2-1))
   res := max of res and (temp + findMaxVal(mTable, x+1, y1-1, y2+1))
   res := max of res and (temp + findMaxVal(mTable, x+1, y1+1, y2))
   res := max of res and (temp + findMaxVal(mTable, x+1, y1+1, y2-1))
   res := max of res and (temp + findMaxVal(mTable, x+1, y1+1, y2+1))

   return true if mTable[x, y1, y2] = res
End

Source Code (C++)

#include<iostream>
#define ROW 5
#define COL 4
using namespace std;

int grid[ROW][COL] = {
   {3, 6, 8, 2},
   {5, 2, 4, 3},
   {1, 1, 20, 10},
   {1, 1, 20, 10},
   {1, 1, 20, 10},
};

bool isValidInput(int x, int y1, int y2) {
   return (x >= 0 && x < ROW && y1 >=0 && y1 < COL && y2 >=0 && y2 < COL);
}

int max(int a, int b) {
   return (a>b)?a:b;
}

int findMaxVal(int mTable[ROW][COL][COL], int x, int y1, int y2) {
   if (!isValidInput(x, y1, y2))    //when in invalid cell, return -ve infinity
      return INT_MIN;

   if (x == ROW-1 && y1 == 0 && y2 == COL-1)    //when both traversal is complete  
      return (y1 == y2)? grid[x][y1]: grid[x][y1] + grid[x][y2];

   if (x == ROW-1)       //both traversal are at last row but not completed
      return INT_MIN;

   if (mTable[x][y1][y2] != -1)    //when subproblem is solved
      return mTable[x][y1][y2];

   int answer = INT_MIN;       //initially the answer is -ve infinity

   int temp = (y1 == y2)? grid[x][y1]: grid[x][y1] + grid[x][y2];    //store gain of the current room

   //find answer for all possible value and use maximum of them

   answer = max(answer, temp + findMaxVal(mTable, x+1, y1, y2-1));
   answer = max(answer, temp + findMaxVal(mTable, x+1, y1, y2+1));
   answer = max(answer, temp + findMaxVal(mTable, x+1, y1, y2));

   answer = max(answer, temp + findMaxVal(mTable, x+1, y1-1, y2));
   answer = max(answer, temp + findMaxVal(mTable, x+1, y1-1, y2-1));
   answer = max(answer, temp + findMaxVal(mTable, x+1, y1-1, y2+1));

   answer = max(answer, temp + findMaxVal(mTable, x+1, y1+1, y2));
   answer = max(answer, temp + findMaxVal(mTable, x+1, y1+1, y2-1));
   answer = max(answer, temp + findMaxVal(mTable, x+1, y1+1, y2+1));

   return (mTable[x][y1][y2] = answer); //store the answer in the mTable and return.
}

int findMaxCollection() {
   // Create a memoization table and set all values as -1
   int mTable[ROW][COL][COL];

   for(int i = 0; i<ROW; i++)
      for(int j = 0; j<COL; j++)
         for(int k = 0; k<COL; k++)
            mTable[i][j][k] = -1;

   return findMaxVal(mTable, 0, 0, COL-1);
}

int main() {
   cout << "Maximum collection is " << findMaxCollection();
   return 0;
}

Output

Maximum collection is 73
raja
Published on 10-Jul-2018 14:34:02
Advertisements