// A Memoization based program to find maximum collection
// using two traversals of a grid
using System;
class GFG
{
static readonly int R = 5;
static readonly int C = 4;
// checks whether a given input is valid or not
static bool isValid(int x, int y1, int y2)
{
return (x >= 0 && x < R && y1 >=0 &&
y1 < C && y2 >=0 && y2 < C);
}
// Driver function to collect Math.max value
static int getMaxUtil(int [,]arr, int [,,]mem,
int x, int y1, int y2)
{
/*---------- BASE CASES -----------*/
// if P1 or P2 is at an invalid cell
if (!isValid(x, y1, y2)) return int.MinValue;
// if both traversals reach their destinations
if (x == R-1 && y1 == 0 && y2 == C-1)
return (y1 == y2)? arr[x, y1]: arr[x, y1] + arr[x, y2];
// If both traversals are at last
// row but not at their destination
if (x == R-1) return int.MinValue;
// If subproblem is already solved
if (mem[x, y1, y2] != -1) return mem[x, y1, y2];
// Initialize answer for this subproblem
int ans = int.MinValue;
// this variable is used to store
// gain of current cell(s)
int temp = (y1 == y2)? arr[x, y1]:
arr[x, y1] + arr[x, y2];
/* Recur for all possible cases, then store
and return the one with max value */
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);
}
// This is mainly a wrapper over recursive
// function getMaxUtil(). This function
// creates a table for memoization and
// calls getMaxUtil()
static int geMaxCollection(int [,]arr)
{
// Create a memoization table and
// initialize all entries as -1
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;
}
}
// Calculation maximum value using memoization
// based function getMaxUtil()
return getMaxUtil(arr, mem, 0, 0, C-1);
}
// Driver code
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));
}
}
// This code contributed by Rajput-Ji