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

#include <algorithm>
#include <cassert>
#include <cfloat>
#include <climits>
#include <cmath>
#include <complex>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <ctime>
#include <functional>
#include <iomanip>
#include <iostream>
#include <list>
#include <map>
#include <memory>
#include <numeric>
#include <queue>
#include <set>
#include <sstream>
#include <stack>
#include <string>
#include <utility>
#include <vector>

using namespace std;

#if __GNUC__
#include <tr1/unordered_map>
#include <tr1/unordered_set>
using namespace tr1;
#else
#include <unordered_map>
#include <unordered_set>
#endif

#ifdef __GNUC__
template <class T> int popcount(T n);
template <> int popcount(unsigned int n) { return __builtin_popcount(n); }
template <> int popcount(int n) { return __builtin_popcount(n); }
template <> int popcount(unsigned long long n) {
  return __builtin_popcountll(n);
}
template <> int popcount(long long n) { return __builtin_popcountll(n); }
#else
#define __typeof__ decltype
template <class T> int popcount(T n) {
  return n ? 1 + popcount(n & (n - 1)) : 0;
}
#endif

#define rep(i, n) for (int i = 0; i < (int)n; ++i)
#define foreach(it, c)                                                         \\
  for (__typeof__((c).begin()) it = (c).begin(); it != (c).end(); ++it)
#define rforeach(it, c)                                                        \\
  for (__typeof__((c).rbegin()) it = (c).rbegin(); it != (c).rend(); ++it)
#define all(c) (c).begin(), (c).end()
#define rall(c) (c).rbegin(), (c).rend()
#define CL(arr, val) memset(arr, val, sizeof(arr))
#define COPY(dest, src) memcpy(dest, src, sizeof(dest))

template <class T> void max_swap(T &a, const T &b) { a = max(a, b); }
template <class T> void min_swap(T &a, const T &b) { a = min(a, b); }

typedef long long ll;
typedef pair<int, int> pint;

template <class T> string to_s(const T &a) {
  ostringstream os;
  os << a;
  return os.str();
}

template <class T>
void print(T a, int n, int br = 1, const string &deli = ", ") {
  cout << "{ ";
  for (int i = 0; i < n; ++i) {
    cout << a[i];
    if (i + 1 != n)
      cout << deli;
  }
  cout << " }";
  while (br--)
    cout << endl;
}
template <class T>
void print(const vector<T> &v, int br = 1, const string &deli = ", ") {
  print(v, v.size(), br, deli);
}
template <class T> void print2d(T a, int w, int h, int width = -1, int br = 1) {
  for (int i = 0; i < h; ++i) {
    for (int j = 0; j < w; ++j) {
      if (width != -1)
        cout.width(width);
      cout << a[i][j] << ' ';
    }
    cout << endl;
  }
  while (br--)
    cout << endl;
}

template <class T> void input(T &a, int n) {
  for (int i = 0; i < n; ++i)
    cin >> a[i];
}
template <class T, class U> void input(T &a, U &b, int n) {
  for (int i = 0; i < n; ++i)
    cin >> a[i] >> b[i];
}

const double EPS = 1e-8;
const double PI = acos(-1.0);
const int dx[] = {0, 1, 0, -1};
const int dy[] = {1, 0, -1, 0};
bool valid_pos(int x, int y, int w, int h) {
  return 0 <= x && x < w && 0 <= y && y < h;
}

typedef pair<ll, ll> P;
ll enc(int *s) {
  ll res = 0;
  for (int i = 0; i < 5; ++i)
    res = (res << 8) | s[i];
  return res;
}
P encode(int *s) { return P(enc(s + 1), enc(s + 5)); }
ll dec(int *s, ll d) {
  for (int i = 4; i >= 0; --i, d >>= 8)
    s[i] = d & 0xff;
}
void decode(int *s, const P &p) {
  dec(s + 1, p.first);
  dec(s + 5, p.second);
}

int n, a[128];

int res, possi_max;
int sack[11];
set<P> memo[101];
void dfs(int d) {
  static const int M = 88;
  if (res == possi_max || sack[10] + (n - d) <= res ||
      (d < M && memo[d].count(encode(sack))))
    return;
  else if (d == n) {
    res = sack[10];
    return;
  }
  if (d < M)
    memo[d].insert(encode(sack));

  for (int i = 10 - a[d]; i >= 0; --i) {
    if (sack[i] > 0) {
      int j = a[d] + i;

      --sack[i];
      ++sack[j];

      dfs(d + 1);

      ++sack[i];
      --sack[j];
    }
  }
}

int solve() {
  sort(a, a + n, greater<int>());

  for (int i = 0; i < 100; ++i)
    memo[i].clear();

  possi_max = accumulate(a, a + n, 0) / 10;
  res = 0;
  dfs(0);

  return res;
}
int main() {
  ios::sync_with_stdio(false);

  sack[0] = 114514;
  while (cin >> n, n) {
    input(a, n);
    cout << solve() << endl;
  }
}

Error: MLE

Fixed submission:

#include <algorithm>
#include <cassert>
#include <cfloat>
#include <climits>
#include <cmath>
#include <complex>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <ctime>
#include <functional>
#include <iomanip>
#include <iostream>
#include <list>
#include <map>
#include <memory>
#include <numeric>
#include <queue>
#include <set>
#include <sstream>
#include <stack>
#include <string>
#include <utility>
#include <vector>

using namespace std;

#if __GNUC__
#include <tr1/unordered_map>
#include <tr1/unordered_set>
using namespace tr1;
#else
#include <unordered_map>
#include <unordered_set>
#endif

#ifdef __GNUC__
template <class T> int popcount(T n);
template <> int popcount(unsigned int n) { return __builtin_popcount(n); }
template <> int popcount(int n) { return __builtin_popcount(n); }
template <> int popcount(unsigned long long n) {
  return __builtin_popcountll(n);
}
template <> int popcount(long long n) { return __builtin_popcountll(n); }
#else
#define __typeof__ decltype
template <class T> int popcount(T n) {
  return n ? 1 + popcount(n & (n - 1)) : 0;
}
#endif

#define rep(i, n) for (int i = 0; i < (int)n; ++i)
#define foreach(it, c)                                                         \\
  for (__typeof__((c).begin()) it = (c).begin(); it != (c).end(); ++it)
#define rforeach(it, c)                                                        \\
  for (__typeof__((c).rbegin()) it = (c).rbegin(); it != (c).rend(); ++it)
#define all(c) (c).begin(), (c).end()
#define rall(c) (c).rbegin(), (c).rend()
#define CL(arr, val) memset(arr, val, sizeof(arr))
#define COPY(dest, src) memcpy(dest, src, sizeof(src))

template <class T> void max_swap(T &a, const T &b) { a = max(a, b); }
template <class T> void min_swap(T &a, const T &b) { a = min(a, b); }

typedef long long ll;
typedef pair<int, int> pint;

template <class T> string to_s(const T &a) {
  ostringstream os;
  os << a;
  return os.str();
}

template <class T>
void print(T a, int n, int br = 1, const string &deli = ", ") {
  cout << "{ ";
  for (int i = 0; i < n; ++i) {
    cout << a[i];
    if (i + 1 != n)
      cout << deli;
  }
  cout << " }";
  while (br--)
    cout << endl;
}
template <class T>
void print(const vector<T> &v, int br = 1, const string &deli = ", ") {
  print(v, v.size(), br, deli);
}
template <class T> void print2d(T a, int w, int h, int width = -1, int br = 1) {
  for (int i = 0; i < h; ++i) {
    for (int j = 0; j < w; ++j) {
      if (width != -1)
        cout.width(width);
      cout << a[i][j] << ' ';
    }
    cout << endl;
  }
  while (br--)
    cout << endl;
}

template <class T> void input(T &a, int n) {
  for (int i = 0; i < n; ++i)
    cin >> a[i];
}
template <class T, class U> void input(T &a, U &b, int n) {
  for (int i = 0; i < n; ++i)
    cin >> a[i] >> b[i];
}

const double EPS = 1e-8;
const double PI = acos(-1.0);
const int dx[] = {0, 1, 0, -1};
const int dy[] = {1, 0, -1, 0};
bool valid_pos(int x, int y, int w, int h) {
  return 0 <= x && x < w && 0 <= y && y < h;
}

typedef pair<ll, ll> P;
ll enc(int *s) {
  ll res = 0;
  for (int i = 0; i < 5; ++i)
    res = (res << 8) | s[i];
  return res;
}
P encode(int *s) { return P(enc(s + 1), enc(s + 5)); }
ll dec(int *s, ll d) {
  for (int i = 4; i >= 0; --i, d >>= 8)
    s[i] = d & 0xff;
}
void decode(int *s, const P &p) {
  dec(s + 1, p.first);
  dec(s + 5, p.second);
}

int n, a[128];

int res, possi_max;
int sack[11];
set<P> memo[128];
void dfs(int d) {
  if (res == possi_max || sack[10] + (n - d) <= res ||
      memo[d].count(encode(sack)))
    return;
  else if (d == n) {
    res = sack[10];
    return;
  }

  memo[d].insert(encode(sack));

  for (int i = 10 - a[d]; i >= 0; --i) {
    if (sack[i] > 0) {
      int j = a[d] + i;

      --sack[i];
      ++sack[j];

      dfs(d + 1);

      ++sack[i];
      --sack[j];
    }
  }
}
int remove_clear() {
  int s[11];
  CL(s, 0);
  for (int i = 0; i < n; ++i)
    ++s[a[i]];

  int res = 0;
  for (int i = 1; i <= 4; ++i) {
    int t = min(s[i], s[10 - i]);
    res += t;
    s[i] -= t;
    s[10 - i] -= t;
  }
  res += s[5] / 2;
  s[5] -= s[5] / 2 * 2;

  // int mini = 10;
  // for (int i = 9; i >= 1; --i)
  //     if (s[i] > 0)
  //         mini = i;

  n = 0;
  for (int i = 1; i <= 9; ++i)
    while (s[i] > 0)
      a[n++] = i, --s[i];

  return res;
}

void test() {
  n = 100;
  for (int i = 0; i < n; ++i)
    a[i] = rand() % 10 + 1;
}
int main() {
  ios::sync_with_stdio(false);

  sack[0] = 114514;
  while (cin >> n, n) {
    input(a, n);

    sort(a, a + n, greater<int>());

    for (int i = 0; i < n; ++i)
      memo[i].clear();

    possi_max = accumulate(a, a + n, 0) / 10;
    res = 0;
    dfs(0);

    cout << res << endl;
  }
}