#include #include #include #include #include #include #include #include #include #include #include #include #include #include #include using namespace std; const int INF = 0x3f3f3f3f; const double EPS = 0.000000001; const double PI = 3.141592653589793; const long long LLINF = 99999999999999999LL; const int MAX_N = 10002; int N; int A[MAX_N][MAX_N], D[MAX_N][MAX_N], sumLeft[MAX_N][MAX_N], sumRight[MAX_N][MAX_N]; set < int > setLeft, setRight; int main() { /* #ifndef ONLINE_JUDGE freopen("data.in", "r", stdin); #endif */ cin >> N; for(int i = 1; i <= N; ++i) { for(int j = 1; j <= N; ++j) { cin >> A[i][j]; } } for(int i = 1; i <= N; ++i) { for(int j = 1; j <= N; ++j) { sumLeft[i][j] = sumLeft[i][j - 1] + A[i][j]; } for(int j = N; j >= 1; --j) { sumRight[i][j] = sumRight[i][j + 1] + A[i][j]; } } int minVal = 0; for(int j = 1; j <= N; ++j) { D[N][j] = sumLeft[N][j] - minVal; minVal = min(minVal, sumLeft[N][j]); } minVal = 0; for(int j = N; j >= 1; --j) { D[N][j] = max(D[N][j], sumRight[N][j] - minVal); minVal = min(minVal, sumRight[N][j]); } set < int > :: iterator it; for(int i = N - 1; i >= 1; --i) { setLeft.clear(); setRight.clear(); for(int j = 1; j <= N; ++j) { setRight.insert(sumLeft[i][j] + D[i + 1][j]); } for(int j = 1; j <= N; ++j) { int maxVal = max(0, D[i + 1][j]); setRight.erase(sumLeft[i][j] + D[i + 1][j]); if(!setLeft.empty()) { it = setLeft.end(); --it; maxVal = max(maxVal, *it - sumRight[i][j]); } if(!setRight.empty()) { it = setRight.end(); --it; maxVal = max(maxVal, *it - sumLeft[i][j]); } setLeft.insert(sumRight[i][j] + D[i + 1][j]); D[i][j] = A[i][j] + maxVal; } } int ans = A[1][1]; for(int i = 1; i <= N; ++i) { for(int j = 1; j <= N; ++j) { ans = max(ans, D[i][j]); } } printf("%d\n", ans); return 0; }