Problem p01529 (C++) — buggy submission, verdict: Memory Limit Exceeded

#include <algorithm>
#include <cassert>
#include <cmath>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <iostream>
#include <map>
#include <queue>
#include <set>
#include <sstream>
#include <stack>
#include <string>
#include <vector>

using namespace std;

#define FOR(i, k, n) for (int i = (k); i < (int)(n); ++i)
#define REP(i, n) FOR(i, 0, n)
#define FORIT(i, c)                                                            \\
  for (__typeof((c).begin()) i = (c).begin(); i != (c).end(); ++i)

template <class T> void debug(T begin, T end) {
  for (T i = begin; i != end; ++i)
    cerr << *i << " ";
  cerr << endl;
}
inline bool valid(int x, int y, int W, int H) {
  return (x >= 0 && y >= 0 && x < W && y < H);
}

typedef long long ll;
const long long INF = 100000000000000000LL;
const double EPS = 1e-8;
const int MOD = 1000000007;
int dx[8] = {1, 0, -1, 0, 1, -1, -1, 1};
int dy[8] = {0, 1, 0, -1, 1, 1, -1, -1};
ll dp[4001][4001];
short K[4001][4001];
ll accum[4001];

int main() {
  int N;
  cin >> N;
  ll *w = dp[0];
  REP(i, N) cin >> w[i];
  accum[0] = 0;
  for (int i = 0; i < N; i++) {
    accum[i + 1] = accum[i] + w[i];
  }
  memset(K, -1, sizeof(K));
  REP(i, N + 1) REP(j, N + 1) dp[i][j] = INF;
  REP(i, N) {
    // dp[i][i] = 0;
    // K[i][i] = i;
    dp[i][i + 1] = 0;
    K[i][i + 1] = i;
  }
  for (int w = 2; w <= N; w++) {
    for (int i = 0; i + w <= N; i++) {
      int j = i + w;
      for (int k = K[i][j - 1]; k <= K[i + 1][j]; k++) {
        ll x = dp[i][k] + dp[k][j] + (accum[j] - accum[i]);
        if (dp[i][j] >= x) {
          dp[i][j] = x;
          K[i][j] = k;
        }
      }
      // printf("dp[%d][%d] = %lld K: %d -> %d\\n", i, j, dp[i][j], K[i][j - 1],
      // K[i + 1][j]);
    }
  }
  cout << dp[0][N] << endl;
  return 0;
}

Error: MLE

Fixed submission:

#include <algorithm>
#include <cassert>
#include <cmath>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <iostream>
#include <map>
#include <queue>
#include <set>
#include <sstream>
#include <stack>
#include <string>
#include <vector>

using namespace std;

#define FOR(i, k, n) for (int i = (k); i < (int)(n); ++i)
#define REP(i, n) FOR(i, 0, n)
#define FORIT(i, c)                                                            \\
  for (__typeof((c).begin()) i = (c).begin(); i != (c).end(); ++i)

template <class T> void debug(T begin, T end) {
  for (T i = begin; i != end; ++i)
    cerr << *i << " ";
  cerr << endl;
}
inline bool valid(int x, int y, int W, int H) {
  return (x >= 0 && y >= 0 && x < W && y < H);
}

typedef long long ll;
const long long INF = 100000000000000000LL;
const double EPS = 1e-8;
const int MOD = 1000000007;
int dx[8] = {1, 0, -1, 0, 1, -1, -1, 1};
int dy[8] = {0, 1, 0, -1, 1, 1, -1, -1};
ll dp[4001][4001];
ll wt[4001][4001];
short K[4001][4001];

int main() {
  int N;
  cin >> N;
  ll *w = dp[0];
  REP(i, N) cin >> w[i];
  for (int i = 0; i < N; i++) {
    wt[i][i] = 0;
    for (int j = i; j < N; j++) {
      wt[i][j + 1] = wt[i][j] + w[j];
    }
  }
  memset(K, -1, sizeof(K));
  REP(i, N + 1) REP(j, N + 1) dp[i][j] = INF;
  REP(i, N) {
    // dp[i][i] = 0;
    // K[i][i] = i;
    dp[i][i + 1] = 0;
    K[i][i + 1] = i;
  }
  for (int w = 2; w <= N; w++) {
    for (int i = 0; i + w <= N; i++) {
      int j = i + w;
      for (int k = K[i][j - 1]; k <= K[i + 1][j]; k++) {
        ll x = dp[i][k] + dp[k][j] + wt[i][j];
        if (dp[i][j] >= x) {
          dp[i][j] = x;
          K[i][j] = k;
        }
      }
      // printf("dp[%d][%d] = %lld K: %d -> %d\\n", i, j, dp[i][j], K[i][j - 1],
      // K[i + 1][j]);
    }
  }
  cout << dp[0][N] << endl;
  return 0;
}