Problem p03782 (C++)

Buggy submission (status: Memory Limit Exceeded):
#include <algorithm>
#include <fstream>
#include <iostream>
using namespace std;

#define NMAX 5002

int L[NMAX][NMAX], LL[NMAX], R[NMAX][NMAX], RR[NMAX], S[NMAX][NMAX], v[NMAX];

void build_left(const int n, const int K) {
  L[0][0] = 1;
  for (int i = 1; i <= n; i++) {
    for (int j = 0; j <= K; j++) {
      L[i][j] = L[i - 1][j];
    }
    for (int j = 0; j <= K && j + v[i] <= K; j++) {
      if (L[i - 1][j]) {
        L[i][j + v[i]] = 1;
      }
    }
  }
  for (int i = 0; i <= n; i++) {
    LL[i] = -1;
    for (int j = K - 1; j >= 0; j--) {
      if (L[i][j]) {
        LL[i] = j;
        break;
      }
    }
  }
}

void build_right(const int n, const int K) {
  R[n + 1][0] = 1;
  for (int i = n; i >= 1; i--) {
    for (int j = 0; j <= K; j++) {
      R[i][j] = R[i + 1][j];
    }
    for (int j = 0; j <= K && j + v[i] <= K; j++) {
      if (R[i + 1][j]) {
        R[i][j + v[i]] = 1;
      }
    }
  }
  for (int i = 1; i <= n + 1; i++) {
    RR[i] = -1;
    for (int j = K - 1; j >= 0; j--) {
      if (R[i][j]) {
        RR[i] = j;
        break;
      }
    }
  }
  for (int i = 1; i <= n + 1; i++) {
    S[i][0] = R[i][0];
    for (int j = 1; j <= K; j++) {
      S[i][j] = S[i][j - 1] + R[i][j];
    }
  }
}

int get_sum(const int poz, const int st, const int dr) {
  if (st > dr)
    return 0;
  if (st == 0)
    return S[poz][dr];
  return S[poz][dr] - S[poz][st - 1];
}

bool good(const int poz, const int K, const int n) {
  const int st = K - v[poz];
  if (poz > 1 && LL[poz - 1] >= st) {
    return true;
  }
  if (poz < n && RR[poz + 1] >= st) {
    return true;
  }
  if (poz == 1 || poz == n) {
    return false;
  }
  for (int i = 1; i <= K; i++) {
    if (L[poz - 1][i] == 0) {
      continue;
    }
    int x = max(st - i, 0);
    int y = K - i - 1;
    if (x > y || y <= 0) {
      continue;
    }
    if (get_sum(poz + 1, x, y) >= 1) {
      return true;
    }
  }
  return false;
}

int main() {
  ios_base::sync_with_stdio(false);

  int n, K, k = 0;
  // ifstream cin("code.in");
  cin >> n >> K;
  for (int i = 1; i <= n; i++) {
    int x;
    cin >> x;
    if (x < K) {
      v[++k] = x;
    }
  }
  n = k;

  build_left(n, K);
  build_right(n, K);

  int sol = n;
  for (int i = 1; i <= n; i++) {
    if (good(i, K, n)) {
      sol--;
    }
  }

  cout << sol << '\n';
  return 0;
}


Fixed submission:
#include <algorithm>
#include <fstream>
#include <iostream>
using namespace std;

#define NMAX 5002

short L[NMAX][NMAX], LL[NMAX], R[NMAX][NMAX], RR[NMAX], S[NMAX][NMAX];
int v[NMAX];

void build_left(const int n, const int K) {
  L[0][0] = 1;
  for (int i = 1; i <= n; i++) {
    for (int j = 0; j <= K; j++) {
      L[i][j] = L[i - 1][j];
    }
    for (int j = 0; j <= K && j + v[i] <= K; j++) {
      if (L[i - 1][j]) {
        L[i][j + v[i]] = 1;
      }
    }
  }
  for (int i = 0; i <= n; i++) {
    LL[i] = -1;
    for (int j = K - 1; j >= 0; j--) {
      if (L[i][j]) {
        LL[i] = j;
        break;
      }
    }
  }
}

void build_right(const int n, const int K) {
  R[n + 1][0] = 1;
  for (int i = n; i >= 1; i--) {
    for (int j = 0; j <= K; j++) {
      R[i][j] = R[i + 1][j];
    }
    for (int j = 0; j <= K && j + v[i] <= K; j++) {
      if (R[i + 1][j]) {
        R[i][j + v[i]] = 1;
      }
    }
  }
  for (int i = 1; i <= n + 1; i++) {
    RR[i] = -1;
    for (int j = K - 1; j >= 0; j--) {
      if (R[i][j]) {
        RR[i] = j;
        break;
      }
    }
  }
  for (int i = 1; i <= n + 1; i++) {
    S[i][0] = R[i][0];
    for (int j = 1; j <= K; j++) {
      S[i][j] = S[i][j - 1] + R[i][j];
    }
  }
}

int get_sum(const int poz, const int st, const int dr) {
  if (st > dr)
    return 0;
  if (st == 0)
    return S[poz][dr];
  return S[poz][dr] - S[poz][st - 1];
}

bool good(const int poz, const int K, const int n) {
  const int st = K - v[poz];
  if (poz > 1 && LL[poz - 1] >= st) {
    return true;
  }
  if (poz < n && RR[poz + 1] >= st) {
    return true;
  }
  if (poz == 1 || poz == n) {
    return false;
  }
  for (int i = 1; i <= K; i++) {
    if (L[poz - 1][i] == 0) {
      continue;
    }
    int x = max(st - i, 0);
    int y = K - i - 1;
    if (x > y || y <= 0) {
      continue;
    }
    if (get_sum(poz + 1, x, y) >= 1) {
      return true;
    }
  }
  return false;
}

int main() {
  ios_base::sync_with_stdio(false);

  int n, K, k = 0;
  // ifstream cin("code.in");
  cin >> n >> K;
  for (int i = 1; i <= n; i++) {
    int x;
    cin >> x;
    if (x < K) {
      v[++k] = x;
    }
  }
  n = k;

  build_left(n, K);
  build_right(n, K);

  int sol = n;
  for (int i = 1; i <= n; i++) {
    if (good(i, K, n)) {
      sol--;
    }
  }

  cout << sol << '\n';
  return 0;
}