Problem p03782 (C++)

Buggy submission (status: Memory Limit Exceeded):
#include <bits/stdc++.h>

inline int read() {
  int x = 0, f = 1;
  char ch = getchar();
  while (ch < '0' || ch > '9') {
    if (ch == '-')
      f = -1;
    ch = getchar();
  }
  while (ch >= '0' && ch <= '9') {
    x = x * 10 + ch - '0';
    ch = getchar();
  }
  return x * f;
}
using namespace std;
#define lowbit(x) ((x) & (-x))
const int maxn = 5000 + 50;
int n, K, prefix[maxn][maxn], suffix[maxn][maxn], sum[maxn][maxn], a[maxn];

int main(int argc, char *argv[]) {
  n = read(), K = read();
  for (int i = 1; i <= n; ++i)
    a[i] = read();
  sort(a + 1, a + n + 1);
  int ans = n;
  int base = n;
  while (n >= 1 && a[n] >= K)
    --n;
  prefix[0][0] = suffix[n + 1][0] = 1;
  for (int i = 1; i <= n; ++i) {
    for (int j = 0; j < K; ++j)
      if (prefix[i - 1][j]) {
        prefix[i][j] = 1;
        if (j + a[i] <= K)
          prefix[i][j + a[i]] = 1;
      }
  }
  for (int i = n; i >= 1; --i) {
    for (int j = 0; j < K; ++j)
      if (suffix[i + 1][j]) {
        suffix[i][j] = 1;
        if (j + a[i] <= K)
          suffix[i][j + a[i]] = 1;
      }
    for (int j = 1; j < K; ++j)
      sum[i][j] = sum[i][j - 1] + suffix[i][j];
  }
  for (int i = 1; i <= n; ++i) {
    int l = K - a[i], r = K - 1, ok = 1;
    for (int j = 0; j < K; ++j)
      if (prefix[i - 1][j]) {
        if (j >= l) {
          ok = 0;
          break;
        } else {
          int rangel = l - j, ranger = r - j;
          if (sum[i + 1][ranger] - sum[i + 1][rangel - 1]) {
            ok = 0;
            break;
          }
        }
      }
    ans -= ok;
  }
  printf("%d\n", base - ans);
  return 0;
}

Fixed submission:
#include <bits/stdc++.h>

inline int read() {
  int x = 0, f = 1;
  char ch = getchar();
  while (ch < '0' || ch > '9') {
    if (ch == '-')
      f = -1;
    ch = getchar();
  }
  while (ch >= '0' && ch <= '9') {
    x = x * 10 + ch - '0';
    ch = getchar();
  }
  return x * f;
}
using namespace std;
#define lowbit(x) ((x) & (-x))
const int maxn = 5000 + 50;
int n, K, a[maxn];
short prefix[maxn][maxn], suffix[maxn][maxn], sum[maxn][maxn];

int main(int argc, char *argv[]) {
  n = read(), K = read();
  for (int i = 1; i <= n; ++i)
    a[i] = read();
  sort(a + 1, a + n + 1);
  int ans = n;
  int base = n;
  while (n >= 1 && a[n] >= K)
    --n;
  prefix[0][0] = suffix[n + 1][0] = 1;
  for (int i = 1; i <= n; ++i) {
    for (int j = 0; j < K; ++j)
      if (prefix[i - 1][j]) {
        prefix[i][j] = 1;
        if (j + a[i] <= K)
          prefix[i][j + a[i]] = 1;
      }
  }
  for (int i = n; i >= 1; --i) {
    for (int j = 0; j < K; ++j)
      if (suffix[i + 1][j]) {
        suffix[i][j] = 1;
        if (j + a[i] <= K)
          suffix[i][j + a[i]] = 1;
      }
    for (int j = 1; j < K; ++j)
      sum[i][j] = sum[i][j - 1] + suffix[i][j];
  }
  for (int i = 1; i <= n; ++i) {
    int l = K - a[i], r = K - 1, ok = 1;
    for (int j = 0; j < K; ++j)
      if (prefix[i - 1][j]) {
        if (j >= l) {
          ok = 0;
          break;
        } else {
          int rangel = l - j, ranger = r - j;
          if (sum[i + 1][ranger] - sum[i + 1][rangel - 1]) {
            ok = 0;
            break;
          }
        }
      }
    ans -= ok;
  }
  printf("%d\n", base - ans);
  return 0;
}