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

#include <algorithm>
#include <climits>
#include <cmath>
#include <iostream>
#include <set>
#include <string>
#include <vector>
using namespace std;

int N;
int D[110];
int A[110];
int dp[110][60000];

int factorial(int x) {
  if (x == 1)
    return 1;
  return x * factorial(x - 1);
}

int enc(int a, int b, int c, int d, int e, int f, int g) {
  vector<int> v;
  int t[7] = {a, b, c, d, e, f, g};
  int ret = 0;
  for (int i = 0; i < 7; i++)
    v.push_back(i);
  for (int i = 0; i < 7; i++) {
    int k = find(v.begin(), v.end(), t[i] - 1) - v.begin();
    ret += factorial(7 - i) * k;
    v.erase(v.begin() + k);
  }
  return ret;
}

int max_at(int i) {
  int m[] = {1, 2, 3, 4, 5, 6, 7};
  int ret = 0;
  do {
    int s = enc(m[0], m[1], m[2], m[3], m[4], m[5], m[6]);
    ret = max(ret, dp[i][s]);
  } while (next_permutation(m, m + 7));
  return ret;
}

int main() {
  cin >> N;
  for (int i = 0; i < N; i++)
    cin >> D[i];
  for (int i = 0; i < N; i++)
    cin >> A[i];

  int m[] = {1, 2, 3, 4, 5, 6, 7};
  do {
    int score = 0;
    for (int i = 0; i < min(N, 7); i++) {
      for (int b = max(0, i - D[i]); b <= min(i + D[i], 6); b++) {
        if (i != b && m[i] > m[b])
          score += A[i];
      }
    }
    dp[7][enc(m[0], m[1], m[2], m[3], m[4], m[5], m[6])] = score;
  } while (next_permutation(m, m + min(7, N)));

  for (int i = 7; i < N; i++) {
    int m[] = {1, 2, 3, 4, 5, 6, 7};
    do {
      int s = enc(m[0], m[1], m[2], m[3], m[4], m[5], m[6]);

      for (int k = 1; k <= 8; k++) {
        int mc[8] = {0, 0, 0, 0, 0, 0, 0, 0};
        int mc2[7] = {0, 0, 0, 0, 0, 0, 0};
        for (int j = 0; j < 7; j++)
          mc[j] = m[j];
        mc[7] = k;
        for (int j = 0; j < 7; j++) {
          if (mc[j] >= k)
            mc[j]++;
        }
        for (int j = 1; j < 8; j++) {
          mc2[j - 1] = mc[j];
          if (mc[j] > mc[0])
            mc2[j - 1]--;
        }
        int ns = enc(mc2[0], mc2[1], mc2[2], mc2[3], mc2[4], mc2[5], mc2[6]);
        int score = 0;
        for (int j = max(0, 7 - D[i]); j < 7; j++) {
          if (mc[j] < mc[7])
            score += A[i];
        }
        for (int j = max(0, i - 7); j < i; j++) {
          if (mc[7 - (i - j)] > mc[7] && i - j <= D[j]) {
            score += A[j];
          }
        }
        dp[i + 1][ns] = max(dp[i + 1][ns], score + dp[i][s]);
      }
    } while (next_permutation(m, m + 7));
  }
  cout << max_at(max(N, 7)) << "\\n";
  return 0;
}

Error: MLE

Fixed submission:

#include <algorithm>
#include <climits>
#include <cmath>
#include <iostream>
#include <string>
#include <vector>
using namespace std;

#define MASK 2100000
int N;
int D[100];
int A[100];
int dp[110][MASK];

int enc(int a, int b, int c, int d, int e, int f, int g) {
  return a * (1 << 18) + b * (1 << 15) + c * (1 << 12) + d * (1 << 9) +
         e * (1 << 6) + f * (1 << 3) + g;
}

int max_at(int i) {
  int m[] = {1, 2, 3, 4, 5, 6, 7};
  int ret = 0;
  do {
    int s = enc(m[0], m[1], m[2], m[3], m[4], m[5], m[6]);
    ret = max(ret, dp[i][s]);
  } while (next_permutation(m, m + 7));
  return ret;
}

int main() {
  cin >> N;
  for (int i = 0; i < N; i++)
    cin >> D[i];
  for (int i = 0; i < N; i++)
    cin >> A[i];

  int m[] = {1, 2, 3, 4, 5, 6, 7};
  do {
    int score = 0;
    for (int i = 0; i < min(N, 7); i++) {
      for (int b = max(0, i - D[i]); b <= min(i + D[i], 6); b++) {
        if (i != b && m[i] > m[b])
          score += A[i];
      }
    }
    dp[7][enc(m[0], m[1], m[2], m[3], m[4], m[5], m[6])] = score;
  } while (next_permutation(m, m + min(7, N)));

  for (int i = 7; i < N; i++) {
    int m[] = {1, 2, 3, 4, 5, 6, 7};
    do {
      int s = enc(m[0], m[1], m[2], m[3], m[4], m[5], m[6]);

      for (int k = 1; k <= 7; k++) {
        int mc[7];
        for (int j = 1; j < 7; j++) {
          mc[j - 1] = m[j];
          if (m[j] > m[0])
            mc[j - 1]--;
        }
        for (int j = 0; j < 6; j++) {
          if (mc[j] >= k)
            mc[j]++;
        }
        mc[6] = k;
        int ns = enc(mc[0], mc[1], mc[2], mc[3], mc[4], mc[5], mc[6]);
        int score = D[i] == 7 ? A[i] : 0;
        for (int j = max(0, 6 - D[i]); j < 6; j++) {
          if (mc[j] < k)
            score += A[i];
        }
        for (int j = i - 7; j < i; j++) {
          if (mc[6 - (i - j)] > mc[6] && i - j <= D[j]) {
            score += A[j];
          }
        }
        dp[i + 1][ns] = max(dp[i + 1][ns], score + dp[i][s]);
      }
    } while (next_permutation(m, m + 7));
  }
  cout << max_at(max(N, 7)) << "\\n";
  return 0;
}