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


#define _CRT_SECURE_NO_WARNINGS
#define _USE_MATH_DEFINES
#include <cfloat>
#include <climits>
#include <cmath>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <ctime>
#include <iostream>
#include <memory>
#include <string>

#include <algorithm>
#include <bitset>
#include <complex>
#include <list>
#include <map>
#include <numeric>
#include <queue>
#include <set>
#include <stack>
#include <vector>

using namespace std;

#ifdef _MSC_VER
#define __typeof__ decltype
#define strtok_r strtok_s
#endif

#define ITER(c) __typeof__((c).begin())
#define FOREACH(it, c) for (ITER(c) it = (c).begin(); it != (c).end(); ++it)
#define RITER(c) __typeof__((c).rbegin())
#define RFOREACH(it, c) for (RITER(c) it = (c).rbegin(); it != (c).rend(); ++it)
#define REP(i, n) REPEAT(i, 0, n)
#define RREP(i, n) RREPEAT(i, 0, n)
#define REPEAT(i, k, n) for (int i = (k); i < ((k) + (n)); ++i)
#define RREPEAT(i, k, n) for (int i = (k) + (n)-1; i >= (k); --i)
#define FROMTO(i, f, t) for (int i = f; i < t; i++)
#define ALL(c) (c).begin(), (c).end()
#define LLPOW(p1, p2) ((ll)pow((double)(p1), (int)p2))
#define ESIZEOF(A) (sizeof(A) / sizeof((A)[0]))
#define CIN_NO_SYNC                                                            \\
  do {                                                                         \\
    cin.tie(0);                                                                \\
    ios_base::sync_with_stdio(false);                                          \\
  } while (0)
#define GETSTR(p) fgets((p), sizeof(p), stdin)
#define CHOMP(p)                                                               \\
  do {                                                                         \\
    char *_q = (p) + strlen(p) - 1;                                            \\
    if (*_q == '\\n' || *_q == '\\r')                                            \\
      *_q = 0;                                                                 \\
  } while (0)
#define FILL(m, v) memset(m, v, sizeof(m))
#define mp make_pair
#define pb push_back
template <class _T> _T MAX(_T p1, _T p2) { return (p1 > p2) ? p1 : p2; }
template <class _T> _T MIN(_T p1, _T p2) { return (p1 < p2) ? p1 : p2; }
template <class _Tv> inline string join(const _Tv &v, string sep = " ") {
  ostringstream s;
  FOREACH(it, v) {
    if (it != v.begin())
      s << sep;
    s << *it;
  };
  return s.str();
}

typedef long long ll;
typedef unsigned long long ull;
typedef double D;
typedef complex<D> P;
typedef vector<int> VI;
typedef vector<VI> VVI;
#define X real()
#define Y imag()
#define EPS (1e-9)
#define DEQ(p1, p2) (abs((p1) - (p2)) < EPS)

#ifdef _DEBUG
template <class _Tv>
inline void _prfe(const char *_n, const _Tv _c, bool _p = false) {
  ITER(_c) _it = _c.begin();
  if (_p) {
    cout << _n << " = [" << endl;
    for (; _it != _c.end(); ++_it)
      cout << "    " << *_it << endl;
    cout << "]" << endl;
  } else {
    cout << _n << " = [ ";
    if (_c.size()) {
      cout << *_it++;
      for (; _it != _c.end(); ++_it)
        cout << ", " << *_it;
    }
    cout << " ]" << endl;
  }
}
ostream &operator<<(ostream &os, const pair<int, int> &p) {
  return (os << "(" << p.first << "," << p.second << ")");
}
#define pf printf
#define pr(n)                                                                  \\
  do {                                                                         \\
    cout << #n " = " << (n) << endl;                                           \\
  } while (0)
#define prfe(n) _prfe(#n, n)
#define prfep(n) _prfe(#n, n, true)
#define dbgchk(n)                                                              \\
  do {                                                                         \\
    if (n)                                                                     \\
      throw;                                                                   \\
  } while (0)
#else
#define pf(...)     /* */
#define pr(...)     /* */
#define prfe(...)   /* */
#define prfep(...)  /* */
#define dbgchk(...) /* */
#endif

int n;
int b[101], f[101];
enum { EMPTY = 0, FULL = 1, USED = 2 };

void dbg() {
  pf("f = ");
  REP(i, n) pf("%2d, ", f[i]);
  pf("\\n");
}

bool move(int i, int v, int n_empty);
bool rec(int n_empty) {
  if (n_empty == 0)
    return true;
  REP(i, n) {
    if (f[i] == EMPTY)
      break;
    if (f[i] == FULL) {
      f[i] = USED;
      dbg();
      if (move(i + 1, b[i], n_empty))
        return true;
      f[i] = FULL;
      dbg();
    }
  }
  return false;
}
bool move(int i, int v, int n_empty) {
  if (v == 0)
    return rec(n_empty);
  FROMTO(j, i, n) {
    if (f[j] != EMPTY)
      continue;
    if (v < b[j])
      continue;
    f[j] = FULL;
    dbg();
    if (move(j + 1, v - b[j], n_empty - 1))
      return true;
    if (i == j && f[j] == EMPTY)
      break;
    f[j] = EMPTY;
    dbg();
  }
  return false;
}

bool solve() {
  sort(b, b + n, greater<int>());
  pf("b = ");
  REP(i, n) pf("%2d, ", b[i]);
  pf("\\n");
  REP(i, n) f[i] = EMPTY;
  f[0] = FULL;
  dbg();
  return rec(n - 1);
}

int main() {
  while (cin >> n && n) {
    REP(i, n) cin >> b[i];
    cout << (solve() ? "YES" : "NO") << endl;
  }
  return 0;
}

Error: MLE

Fixed submission:


#define _CRT_SECURE_NO_WARNINGS
#define _USE_MATH_DEFINES
#include <cfloat>
#include <climits>
#include <cmath>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <ctime>
#include <iostream>
#include <memory>
#include <string>

#include <algorithm>
#include <bitset>
#include <complex>
#include <list>
#include <map>
#include <numeric>
#include <queue>
#include <set>
#include <stack>
#include <vector>

using namespace std;

#ifdef _MSC_VER
#define __typeof__ decltype
#define strtok_r strtok_s
#endif

#define ITER(c) __typeof__((c).begin())
#define FOREACH(it, c) for (ITER(c) it = (c).begin(); it != (c).end(); ++it)
#define RITER(c) __typeof__((c).rbegin())
#define RFOREACH(it, c) for (RITER(c) it = (c).rbegin(); it != (c).rend(); ++it)
#define REP(i, n) REPEAT(i, 0, n)
#define RREP(i, n) RREPEAT(i, 0, n)
#define REPEAT(i, k, n) for (int i = (k); i < ((k) + (n)); ++i)
#define RREPEAT(i, k, n) for (int i = (k) + (n)-1; i >= (k); --i)
#define FROMTO(i, f, t) for (int i = f; i < t; i++)
#define ALL(c) (c).begin(), (c).end()
#define LLPOW(p1, p2) ((ll)pow((double)(p1), (int)p2))
#define ESIZEOF(A) (sizeof(A) / sizeof((A)[0]))
#define CIN_NO_SYNC                                                            \\
  do {                                                                         \\
    cin.tie(0);                                                                \\
    ios_base::sync_with_stdio(false);                                          \\
  } while (0)
#define GETSTR(p) fgets((p), sizeof(p), stdin)
#define CHOMP(p)                                                               \\
  do {                                                                         \\
    char *_q = (p) + strlen(p) - 1;                                            \\
    if (*_q == '\\n' || *_q == '\\r')                                            \\
      *_q = 0;                                                                 \\
  } while (0)
#define FILL(m, v) memset(m, v, sizeof(m))
#define mp make_pair
#define pb push_back
template <class _T> _T MAX(_T p1, _T p2) { return (p1 > p2) ? p1 : p2; }
template <class _T> _T MIN(_T p1, _T p2) { return (p1 < p2) ? p1 : p2; }
template <class _Tv> inline string join(const _Tv &v, string sep = " ") {
  ostringstream s;
  FOREACH(it, v) {
    if (it != v.begin())
      s << sep;
    s << *it;
  };
  return s.str();
}

typedef long long ll;
typedef unsigned long long ull;
typedef double D;
typedef complex<D> P;
typedef vector<int> VI;
typedef vector<VI> VVI;
#define X real()
#define Y imag()
#define EPS (1e-9)
#define DEQ(p1, p2) (abs((p1) - (p2)) < EPS)

#ifdef _DEBUG
template <class _Tv>
inline void _prfe(const char *_n, const _Tv _c, bool _p = false) {
  ITER(_c) _it = _c.begin();
  if (_p) {
    cout << _n << " = [" << endl;
    for (; _it != _c.end(); ++_it)
      cout << "    " << *_it << endl;
    cout << "]" << endl;
  } else {
    cout << _n << " = [ ";
    if (_c.size()) {
      cout << *_it++;
      for (; _it != _c.end(); ++_it)
        cout << ", " << *_it;
    }
    cout << " ]" << endl;
  }
}
ostream &operator<<(ostream &os, const pair<int, int> &p) {
  return (os << "(" << p.first << "," << p.second << ")");
}
#define pf printf
#define pr(n)                                                                  \\
  do {                                                                         \\
    cout << #n " = " << (n) << endl;                                           \\
  } while (0)
#define prfe(n) _prfe(#n, n)
#define prfep(n) _prfe(#n, n, true)
#define dbgchk(n)                                                              \\
  do {                                                                         \\
    if (n)                                                                     \\
      throw;                                                                   \\
  } while (0)
#else
#define pf(...)     /* */
#define pr(...)     /* */
#define prfe(...)   /* */
#define prfep(...)  /* */
#define dbgchk(...) /* */
#endif

int n;
set<vector<int>> dp[51][101];

bool rec(VI &vi1, VI &vi2) {
  prfe(vi1);
  prfe(vi2);
  int mx = 0;
  if (vi2.size() == 0)
    return true;
  FOREACH(it, vi1) { mx = MAX(mx, *it); }
  if (mx < vi2[0])
    return false;

  int m = vi1.size();
  REP(i, m) {
    int v = vi1[i];
    FOREACH(it, dp[n][v]) {
      vector<int> vi1n = vi1, vi2n;
      vi1n.erase(vi1n.begin(), vi1n.begin() + i);
      unsigned int i3 = 0;
      // prfe(vi2);
      // prfe(*it);
      FOREACH(jt, vi2) {
        if (i3 < (*it).size() && *jt == (*it)[i3]) {
          vi1n.pb(*jt);
          i3++;
        } else {
          vi2n.pb(*jt);
        }
      }
      if ((*it).size() != i3)
        continue;
      if (rec(vi1n, vi2n))
        return true;
    }
  }

  return false;
}

bool solve(VI &vi) {
  sort(ALL(vi), greater<int>());

  REP(i, 51) REP(j, 101) { dp[i][j].clear(); }

  vector<int> vi1;
  vi1.pb(vi[0]);
  vi.erase(vi.begin());

  int mx = 0;
  if (vi.size() == 0)
    return true;
  FOREACH(it, vi1) { mx = MAX(mx, *it); }

  dp[0][0].insert(vector<int>(0));
  n = vi.size();
  REP(i, n) {
    int c = vi[i];
    REP(j, mx + 1) {
      if (dp[i][j].size() == 0)
        continue;
      FOREACH(it, dp[i][j]) {
        vector<int> t = *it;
        dp[i + 1][j].insert(t);
        if (j + c <= mx) {
          t.pb(c);
          dp[i + 1][j + c].insert(t);
        }
      }
    }
  }
  REP(j, mx + 1) {
    if (dp[n][j].size() == 0)
      continue;
    pf(" [%d] = ", j);
    FOREACH(it, dp[n][j]) { pf("{ %s }, ", join(*it, ", ").c_str()); }
    pf("\\n");
  }

  return rec(vi1, vi);
}

int main() {
  int n, k;
  while (cin >> n && n) {
    VI vi;
    REP(i, n) {
      cin >> k;
      vi.pb(k);
    }
    cout << (solve(vi) ? "YES" : "NO") << endl;
  }
  return 0;
}