#include #include #include #include #define REP(i,a,b) for(i=a;i down) mx = down; if(mx > left) mx = left; if(mx > right) mx = right; *dx1 = *dy1 = *dx2 = *dy2 = 0; if(mx == up) *dx1 = 1; else if(mx == down) *dx2 = -1; else if(mx == left) *dy1 = 1; else if(mx == right) *dy2 = -1; return mx; } /* calculate maximum Bob's candies with the current board (x1,y1)-(x2,y2), (memorized) */ /* Alice moves first:) */ ll solve_max(int x1,int y1,int x2,int y2){ int i, j, k; ll left, right, up, down; int dx1, dy1, dx2, dy2; ll res=0, tmp; if(x1 > x2 || y1 > y2) return 0; if(dp_max[x1][y1][x2][y2] >= 0) return dp_max[x1][y1][x2][y2]; AliceMove(x1,y1,x2,y2,&dx1,&dy1,&dx2,&dy2); x1 += dx1; x2 += dx2; y1 += dy1; y2 += dy2; if(x1 > x2 || y1 > y2){ x1 -= dx1; x2 -= dx2; y1 -= dy1; y2 -= dy2; return 0; } tmp = solve_max(x1+1, y1, x2, y2) + getUp(x1, y1, x2, y2); if(res < tmp) res = tmp; tmp = solve_max(x1, y1, x2-1, y2) + getDown(x1, y1, x2, y2); if(res < tmp) res = tmp; tmp = solve_max(x1, y1+1, x2, y2) + getLeft(x1, y1, x2, y2); if(res < tmp) res = tmp; tmp = solve_max(x1, y1, x2, y2-1) + getRight(x1, y1, x2, y2); if(res < tmp) res = tmp; x1 -= dx1; x2 -= dx2; y1 -= dy1; y2 -= dy2; return dp_max[x1][y1][x2][y2] = res; } int main(){ int T; int i, j, k, l; ll res, tmp1, tmp2; assert( scanf("%d",&T)==1 ); assert( 1 <= T && T <= 25 ); while(T--){ assert( scanf("%d%d",&N,&M)==2 ); assert( 1<=N && N<=50 && 1<=M && M<=50 ); rep(i,N) rep(j,M) assert( scanf("%d",A[i]+j)==1 ); rep(i,N) rep(j,M) assert( 0<=A[i][j] && A[i][j] <= 1000000000 ); calcSum(); rep(i,N) rep(j,M) REP(k,i,N) REP(l,j,M) dp_max[i][j][k][l] = -1; res = 0; tmp1 = solve_max(0, 0, N-1, M-1); /* the maximum number of candies which Bob gets */ tmp2 = allSum - tmp1; /* the number of Alice's candies */ if(tmp1 == tmp2) res = tmp1 + tmp2; /* both are winner*/ else if(tmp1 > tmp2) res = tmp1; /* Bob wins */ else res = tmp2; /* Alice wins */ printf("%lld\n",res); } return 0; }