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

#include <bits/stdc++.h>
using namespace std;
using ll = long long;
#define rep(i, n) for (int(i) = 0; (i) < (int)(n); ++(i))
#define all(x) (x).begin(), (x).end()
#define pb push_back
#define fi first
#define se second
#define dbg(x) cout << #x " = " << ((x)) << endl
template <class T, class U>
ostream &operator<<(ostream &o, const pair<T, U> &p) {
  o << "(" << p.fi << "," << p.se << ")";
  return o;
}
template <class T> ostream &operator<<(ostream &o, const vector<T> &v) {
  o << "[";
  for (T t : v) {
    o << t << ",";
  }
  o << "]";
  return o;
}

const int P = 5040;
int dp[110][P] = {};

int fact[8];

inline vector<int> decode(int x) {
  vector<int> ret(7);
  vector<bool> use(7, false);
  rep(i, 7) {
    int num = x / fact[6 - i];
    x -= fact[6 - i] * num;

    int y = 0, ct = 0;
    while (y < 7) {
      if (!use[y])
        ++ct;

      if (ct == num + 1)
        break;
      ++y;
    }
    use[y] = true;
    ret[i] = y;
  }
  return ret;
}

inline int encode(const vector<int> &p) {
  int ret = 0;
  vector<bool> use(7, false);
  rep(i, 7) {
    int ct = 0;
    for (int j = 0; j < p[i]; ++j)
      ct += !use[j];
    ret += ct * fact[6 - i];
    use[p[i]] = true;
  }

  return ret;
}

inline vector<int> normalize(const vector<int> &p) {
  vector<int> t(p);
  sort(all(t));

  int ct = 0;
  int id[10];
  for (const auto &v : t)
    id[v] = ct++;

  vector<int> ret(7);
  rep(i, 7) ret[i] = id[p[i]];

  return ret;
}

int main() {
  fact[0] = 1;
  for (int i = 1; i < 8; ++i)
    fact[i] = fact[i - 1] * i;

  int n;
  cin >> n;
  vector<int> d(n + 7), a(n + 7);
  rep(i, n) cin >> d[i + 7];
  rep(i, n) cin >> a[i + 7];

  n += 7;
  for (int i = 7; i < n; ++i)
    rep(j, P) {
      vector<int> p = decode(j);

      // i??????????????????????£??????????
      rep(k, 8) {
        vector<int> nx(all(p));
        for (auto &v : nx)
          if (v >= k)
            ++v;
        nx.pb(k);

        int NX = nx.size();
        int add = 0;
        for (int l = 1; l < NX; ++l) {
          if (nx[NX - 1] > nx[NX - 1 - l]) {
            // i???????????????????£??????????
            if (d[i - l] >= l)
              add += a[i - l];
          } else {
            // i???????????????????£??????????
            if (d[i] >= l && i - l >= 7)
              add += a[i];
          }
        }

        nx.erase(nx.begin());
        nx = normalize(nx);
        int idx = encode(nx);
        dp[i + 1][idx] = max(dp[i + 1][idx], dp[i][j] + add);
      }
    }

  cout << *max_element(dp[n], dp[n] + P) << endl;
  return 0;
}

Error: MLE

Fixed submission:

#include <bits/stdc++.h>
using namespace std;
using ll = long long;
#define rep(i, n) for (int(i) = 0; (i) < (int)(n); ++(i))
#define all(x) (x).begin(), (x).end()
#define pb push_back
#define fi first
#define se second

using pi = pair<int, int>;

const int INF = INT_MAX / 3;
const int MASK = (1 << 16) - 1;

int dp[120][1 << 16];
int y[120][1 << 16] = {};

pi par[120][1 << 16];

int main() {
  int n;
  scanf(" %d", &n);

  vector<int> d(n + 20), a(n + 20);
  rep(i, n) scanf(" %d", &d[i + 8]);
  rep(i, n) scanf(" %d", &a[i + 8]);

  for (int i = 7; i < n + 8; ++i) {
    rep(mask, 1 << 16) if (!(mask >> 7 & 1)) {
      rep(j, 16) if (mask >> j & 1) {
        int idx = i + (j - 7);
        if (abs(i - idx) <= d[idx]) {
          y[i][mask] += a[idx];

          // if(mask == (1<<16)-1-(1<<7))
          // {
          //     printf("i, idx %d %d\\n", i-8,idx-8);
          // }
        }
      }
    }
  }

  // rep(i,n+8) printf("y[%d][%d] = %d\\n",
  // i,(1<<16)-1-(1<<7),y[i][(1<<16)-1-(1<<7)]);

  fill(dp[0], dp[120], -INF);
  dp[7][(1 << 8) - 1] = 0;

  pi root(7, (1 << 8) - 1);

  queue<pi> que;
  que.push(pi(7, (1 << 8) - 1));
  while (!que.empty()) {
    pi now = que.front();
    que.pop();
    int i = now.fi, mask = now.se;

    // printf("   NOW %3d , mask = ", i-8);
    // cout << bitset<15>(mask)<<endl;

    // choose next
    for (int j = -7; j <= 8; ++j) {
      int nx = i + j;
      if (nx < 0 || n + 7 < nx)
        continue;

      int nmask;
      if (j <= 0) {
        nmask = (mask << (-j)) | ((1 << (-j)) - 1);
        nmask &= MASK;
      } else {
        int check = (1 << j) - 1;
        if ((mask & check) != check)
          continue;

        nmask = mask >> j;
      }

      // have already eaten
      if (nmask >> 7 & 1)
        continue;

      assert(j != 0);

      int add = y[nx][nmask];
      nmask |= (1 << 7);

      // printf("  ? %3d\\n", nx-8);
      if (dp[nx][nmask] < dp[i][mask] + add) {
        dp[nx][nmask] = dp[i][mask] + add;
        que.push(pi(nx, nmask));

        par[nx][nmask] = now;

        // printf("  PUSH %3d , mask = ", nx-8);
        // cout << bitset<15>(nmask)<<endl;
        // printf("  dp = %d\\n", dp[nx][nmask]);
      }
    }
  }

  int ans = -INF;
  rep(i, 120) rep(j, 1 << 16) ans = max(ans, dp[i][j]);

  // rep(i,120)rep(j,1<<16)
  // {
  //     if(dp[i][j]==ans)
  //     {
  //         printf("i,j %d %d\\n", i-8,j);
  //
  //         pi now(i,j);
  //         while(now!=root)
  //         {
  //             now = par[now.fi][now.se];
  //             printf("    %d %d\\n", now.fi-8,now.se);
  //         }
  //
  //     }
  // }

  printf("%d\\n", ans);
  return 0;
}