Problem p00305 (C++) — buggy submission, verdict: Time Limit Exceeded

#include <bits/stdc++.h>
using namespace std;

int n;
int p[310][310] = {};
int rui[310][310] = {};

typedef struct {
  int num;
  int idx;
} Data;
Data dp[310][310][310] = {};

int getRuiseki(int x1, int y1, int x2, int y2) {
  if (x1 > x2 || y1 > y2)
    return 0;
  x2++;
  y2++;
  return rui[y2][x2] - rui[y2][x1] - rui[y1][x2] + rui[y1][x1];
}

int getDonut(int x1, int y1, int x2, int y2) {
  return getRuiseki(x1, y1, x2, y2) -
         getRuiseki(x1 + 1, y1 + 1, x2 - 1, y2 - 1);
}

int getL(int x1, int x2, int y) {
  return getRuiseki(x1, 0, x2, y) - getRuiseki(x1, 0, x2 - 1, y - 1);
}

int main() {
  cin >> n;
  for (int i = 1; i <= n; i++) {
    for (int j = 1; j <= n; j++) {
      cin >> rui[i][j];
    }
  }

  for (int i = 0; i <= n; i++) {
    for (int j = 0; j <= n; j++) {
      rui[i][j + 1] += rui[i][j];
    }
  }

  for (int j = 0; j <= n; j++) {
    for (int i = 0; i <= n; i++) {
      rui[i + 1][j] += rui[i][j];
    }
  }

  for (int finx = n - 1; finx >= 0; finx--) {
    for (int x = finx; x >= 0; x--) {
      dp[finx][x][n - 1].num = getDonut(x, 0, finx, n - 1);
      dp[finx][x][n - 1].idx = n - 1;
      for (int y = n - 2; y >= 0; y--) {
        int tmp = getDonut(x, 0, finx, y);
        if (tmp > dp[finx][x][y + 1].num) {
          dp[finx][x][y].num = tmp;
          dp[finx][x][y].idx = y;
        } else {
          dp[finx][x][y] = dp[finx][x][y + 1];
        }
      }
    }
  }

  int ans = INT_MIN;
  for (int x = 0; x < n; x++) {
    for (int y = 0; y < n; y++) {
      for (int x2 = x; x2 < n; x2++) {
        ans = max(ans, getDonut(x, y, x2, dp[x2][x][y].idx));
      }
    }
  }

  cout << ans << endl;

  return 0;
}


Error: TLE

Fixed submission:

#include <bits/stdc++.h>
using namespace std;

int n;
int p[310][310] = {};
int rui[310][310] = {};

typedef struct {
  int num;
  int idx;
} Data;
Data dp[310][310][310] = {};

int getRuiseki(int x1, int y1, int x2, int y2) {
  if (x1 > x2 || y1 > y2)
    return 0;
  x2++;
  y2++;
  return rui[y2][x2] - rui[y2][x1] - rui[y1][x2] + rui[y1][x1];
}

int getDonut(int x1, int y1, int x2, int y2) {
  return getRuiseki(x1, y1, x2, y2) -
         getRuiseki(x1 + 1, y1 + 1, x2 - 1, y2 - 1);
}

int getL(int x1, int x2, int y) {
  return getRuiseki(x1, 0, x2, y) - getRuiseki(x1, 0, x2 - 1, y - 1);
}

int main() {
  cin >> n;
  for (int i = 1; i <= n; i++) {
    for (int j = 1; j <= n; j++) {
      cin >> rui[i][j];
    }
  }

  for (int i = 0; i <= n; i++) {
    for (int j = 0; j <= n; j++) {
      rui[i][j + 1] += rui[i][j];
    }
  }

  for (int j = 0; j <= n; j++) {
    for (int i = 0; i <= n; i++) {
      rui[i + 1][j] += rui[i][j];
    }
  }

  /*
  for(int finx = n-1;finx >= 0;finx--){
    for(int x = finx;x >= 0;x--){
      dp[finx][x][n-1].num = getL(x, finx, n-1);
      dp[finx][x][n-1].idx = n-1;
      for(int y = n-2;y >= 0;y--){
        int tmp = getL(x, finx, y);
        if(tmp > dp[finx][x][y+1].num){
          dp[finx][x][y].num = tmp;
          dp[finx][x][y].idx = y;
        }else{
          dp[finx][x][y] = dp[finx][x][y+1];
        }
      }
    }
  }
  */

  int ans = INT_MIN;
  for (int x = 0; x < n; x++) {
    for (int y = 0; y < n; y++) {

      for (int x2 = x; x2 < n; x2++)
        for (int y2 = y; y2 < n; y2++)
          ans = max(ans, getDonut(x, y, x2, y2));

      // for(int x2 = x;x2 < n;x2++){
      // ans = max(ans,getDonut(x,y,x2,dp[x2][x][y].idx));
      //}
    }
  }

  cout << ans << endl;

  return 0;
}