//https://www.geeksforgeeks.org/collect-maximum-points-in-a-grid-using-two-traversals/
#include <bits/stdc++.h>
using namespace std;
#define r 5
#define c 4
bool isSafe (int x,int y1,int y2) {
return (x>=0 && x<r && y1>=0 && y1<c && y2>=0 && y2<c);
}
int func(int a[r][c], int dp[r][c][c], int x,int y1,int y2) {
if (!isSafe(x,y1,y2))
return INT_MIN;
if (x== r-1 && y1== 0 && y2==c-1)
return a[x][y1]+a[x][y2];
if (x== r-1)
return INT_MIN;
if(dp[x][y1][y2]!= -1)
return dp[x][y1][y2];
int dy1[]= {-1,-1,-1,0,0,0,1,1,1};//in each step x increases by 1, but y may become y-1, y+1 or stay as y.
int dy2[]= {-1,0,1,-1,0,1,-1,0,1};//2 moves had to be made simultaneously so, a total of 9 possibilities in each step.
int ans= INT_MIN;
int temp= (y1==y2)?a[x][y1]:a[x][y1]+a[x][y2];
for (int i=0;i<=9;i++) {
ans= max(ans, temp+func(a,dp,x+1,y1+dy1[i],y2+dy2[i]));
}
dp[x][y1][y2]= ans;
return ans;
}
int main() {
int a[r][c] = {{3, 6, 8, 2},{5, 2, 4, 3},{1, 1, 20, 10}, {1, 1, 20, 10}, {1, 1, 20, 10}, };
int dp[r][c][c];// dp[x][y1][y2] is used to store the maximum points that can be collected by starting to traverse from x,y1,y2
memset(dp, -1, sizeof(dp));
cout<< func(a,dp,0,0,c-1);
return 0;
}