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

#include <algorithm>
#include <bitset>
#include <cassert>
#include <cmath>
#include <complex>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <iostream>
#include <queue>
#include <set>
#include <string>
#include <vector>
using namespace std;

#define REP(i, n) for (int i = 0; i < (int)n; ++i)
#define FOR(i, c)                                                              \\
  for (__typeof((c).begin()) i = (c).begin(); i != (c).end(); ++i)
#define ALL(c) (c).begin(), (c).end()
const int INF = 1 << 29;
typedef long long ll;

int a[50];
int n;

bool solve(int now, ll used, ll filled);

set<ll> st[50];

bool select(int now, int id, int vol, ll used, ll filled) {
  if (vol == 0) {
    if (used == (1LL << n) - 1)
      return 1;
    else
      return solve(now + 1, used, filled);
  }
  int sum = 0;
  for (int i = id; i < n; ++i)
    if (!(used >> i & 1))
      sum += a[i];
  if (sum < vol)
    return 0;
  if (st[now].count(filled >> now))
    return 0;
  st[now].insert(filled >> now);
  for (int i = id; i < n; ++i) {
    if (!(used >> i & 1) && vol - a[i] >= 0)
      if (select(now, i + 1, vol - a[i], used | 1LL << i, filled | 1LL << i))
        return 1;
  }
  return 0;
}

bool solve(int now, ll used, ll filled) {
  for (int i = now; i < n; ++i) {
    if (!(used >> i & 1))
      return 0;
    if ((filled >> i & 1) && select(i, i + 1, a[i], used, filled ^ 1LL << i))
      return 1;
  }
  return 0;
}

int main() {
  while (cin >> n, n) {
    REP(i, n) st[i].clear();
    REP(i, n) cin >> a[i];
    if (n == 1) {
      cout << "YES" << endl;
      continue;
    }
    sort(a, a + n, greater<int>());
    if (solve(0, 1, 1))
      cout << "YES" << endl;
    else
      cout << "NO" << endl;
  }
}

Error: MLE

Fixed submission:

#include <algorithm>
#include <bitset>
#include <cassert>
#include <cmath>
#include <complex>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <iostream>
#include <queue>
#include <set>
#include <string>
#include <vector>
using namespace std;

#define REP(i, n) for (int i = 0; i < (int)n; ++i)
#define FOR(i, c)                                                              \\
  for (__typeof((c).begin()) i = (c).begin(); i != (c).end(); ++i)
#define ALL(c) (c).begin(), (c).end()
const int INF = 1 << 29;
typedef long long ll;

int a[50];
int n;

bool solve(int now, ll used, ll filled);

set<ll> st[50];

bool select(int now, int id, int vol, ll used, ll filled) {
  if (vol == 0) {
    if (used == (1LL << n) - 1)
      return 1;
    else
      return solve(now + 1, used, filled);
  }
  if (st[now].count(filled >> now))
    return 0;
  st[now].insert(filled >> now);
  for (int i = id; i < n; ++i) {
    if (!(used >> i & 1) && vol - a[i] >= 0)
      if (select(now, i + 1, vol - a[i], used | 1LL << i, filled | 1LL << i))
        return 1;
  }
  return 0;
}

bool solve(int now, ll used, ll filled) {
  for (int i = now; i < n; ++i) {
    if (!(used >> i & 1))
      return 0;
    if ((filled >> i & 1) && select(i, i + 1, a[i], used, filled ^ 1LL << i))
      return 1;
  }
  return 0;
}

int main() {
  while (cin >> n, n) {
    REP(i, n) st[i].clear();
    REP(i, n) cin >> a[i];
    if (n == 1) {
      cout << "YES" << endl;
      continue;
    }
    sort(a, a + n, greater<int>());
    if (solve(0, 1, 1))
      cout << "YES" << endl;
    else
      cout << "NO" << endl;
  }
}