Problem p01806 (C++)

Buggy submission (status: Time Limit Exceeded):
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;

enum { U, B, L, F, R, D };
struct Dice {
  int face[6];

  Dice() {
    face[F] = 1;
    face[R] = 2;
    face[U] = 3;
    face[B] = 6;
    face[L] = 5;
    face[D] = 4;
  }

  int find_face(int f) {
    for (int i = 0; i < 6; i++) {
      if (face[i] == f)
        return i;
    }
    return -1;
  }

  void turn(int dir) {
    switch (dir) {
    case R:
      rotate(U, R, D, L);
      break;
    case B:
      rotate(U, B, D, F);
      break;
    case L:
      rotate(U, L, D, R);
      break;
    case F:
      rotate(U, F, D, B);
      break;
    case U:
      rotate(F, R, B, L);
      break; // ??????????????????????¨???????
    case D:
      rotate(F, L, B, R);
      break; // ??????????????????????¨???????
    default:
      assert(false);
    }
  }

  int &operator[](int n) { return face[n]; }

  const int &operator[](int n) const { return face[n]; }

  std::vector<Dice> all_rolls() {
    std::vector<Dice> res;
    for (int k = 0; k < 6; k++) {
      for (int i = 0; i < 4; i++) {
        res.push_back(*this);
        turn(R);
      }
      turn(k % 2 == 1 ? U : F);
    }
    return res;
  }

  void rotate(int a, int b, int c, int d) {
    int t = face[d];
    face[d] = face[c];
    face[c] = face[b];
    face[b] = face[a];
    face[a] = t;
  }
};

typedef pair<int, int> P;

Dice dice[15];
int X[15], Y[15];
string rot[15];
map<P, int> pos[15];
int dp[16][1 << 15];
set<P> used[1 << 15];

int main() {
  cin.tie(0);
  ios::sync_with_stdio(false);

  int N;
  while (cin >> N, N) {
    for (int i = 0; i < N; i++) {
      int l, r, f, b, d, u;
      cin >> X[i] >> Y[i];
      cin >> l >> r >> f >> b >> d >> u;
      cin >> rot[i];
      dice[i][L] = l;
      dice[i][R] = r;
      dice[i][F] = f;
      dice[i][B] = b;
      dice[i][D] = d;
      dice[i][U] = u;

      Dice t = dice[i];
      int x = X[i], y = Y[i];
      pos[i].clear();
      pos[i][{x, y}] = t[D];
      for (auto c : rot[i]) {
        if (c == 'L')
          t.turn(L), x--;
        if (c == 'R')
          t.turn(R), x++;
        if (c == 'F')
          t.turn(F), y--;
        if (c == 'B')
          t.turn(B), y++;
        pos[i][{x, y}] = t[D];
      }
    }

    for (int i = 0; i < 1 << N; i++) {
      used[i].clear();
      for (int j = 0; j < N; j++) {
        if (i >> j & 1) {
          for (auto p : pos[j]) {
            int x = p.first.first, y = p.first.second;
            used[i].insert({x, y});
          }
        }
      }
    }

    memset(dp, -1, sizeof dp);
    dp[0][0] = 0;
    for (int i = 0; i < N; i++) {
      for (int j = 0; j < 1 << N; j++) {
        if (dp[i][j] == -1)
          continue;
        int s = dp[i][j];
        for (int k = 0; k < N; k++) {
          int ns = s;
          for (auto p : pos[k]) {
            int x = p.first.first, y = p.first.second;
            int point = p.second;
            if (used[j].count({x, y}))
              continue;
            ns += point;
          }
          dp[i + 1][j | (1 << k)] = max(dp[i + 1][j | (1 << k)], ns);
        }
      }
    }

    int ans = 0;
    for (int j = 0; j < 1 << N; j++) {
      ans = max(ans, dp[N][j]);
    }
    cout << ans << endl;
  }
}

Fixed submission:
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;

enum { U, B, L, F, R, D };
struct Dice {
  int face[6];

  Dice() {
    face[F] = 1;
    face[R] = 2;
    face[U] = 3;
    face[B] = 6;
    face[L] = 5;
    face[D] = 4;
  }

  int find_face(int f) {
    for (int i = 0; i < 6; i++) {
      if (face[i] == f)
        return i;
    }
    return -1;
  }

  void turn(int dir) {
    switch (dir) {
    case R:
      rotate(U, R, D, L);
      break;
    case B:
      rotate(U, B, D, F);
      break;
    case L:
      rotate(U, L, D, R);
      break;
    case F:
      rotate(U, F, D, B);
      break;
    case U:
      rotate(F, R, B, L);
      break; // ??????????????????????¨???????
    case D:
      rotate(F, L, B, R);
      break; // ??????????????????????¨???????
    default:
      assert(false);
    }
  }

  int &operator[](int n) { return face[n]; }

  const int &operator[](int n) const { return face[n]; }

  std::vector<Dice> all_rolls() {
    std::vector<Dice> res;
    for (int k = 0; k < 6; k++) {
      for (int i = 0; i < 4; i++) {
        res.push_back(*this);
        turn(R);
      }
      turn(k % 2 == 1 ? U : F);
    }
    return res;
  }

  void rotate(int a, int b, int c, int d) {
    int t = face[d];
    face[d] = face[c];
    face[c] = face[b];
    face[b] = face[a];
    face[a] = t;
  }
};

typedef pair<int, int> P;

Dice dice[15];
int X[15], Y[15];
string rot[15];
map<P, int> pos[15];
int dp[16][1 << 15];
set<P> used[1 << 15];

int main() {
  cin.tie(0);
  ios::sync_with_stdio(false);

  int N;
  while (cin >> N, N) {
    for (int i = 0; i < N; i++) {
      int l, r, f, b, d, u;
      cin >> X[i] >> Y[i];
      cin >> l >> r >> f >> b >> d >> u;
      cin >> rot[i];
      dice[i][L] = l;
      dice[i][R] = r;
      dice[i][F] = f;
      dice[i][B] = b;
      dice[i][D] = d;
      dice[i][U] = u;

      Dice t = dice[i];
      int x = X[i], y = Y[i];
      pos[i].clear();
      pos[i][{x, y}] = t[D];
      for (auto c : rot[i]) {
        if (c == 'L')
          t.turn(L), x--;
        if (c == 'R')
          t.turn(R), x++;
        if (c == 'F')
          t.turn(F), y--;
        if (c == 'B')
          t.turn(B), y++;
        pos[i][{x, y}] = t[D];
      }
    }

    for (int i = 0; i < 1 << N; i++) {
      used[i].clear();
      for (int j = 0; j < N; j++) {
        if (i >> j & 1) {
          for (auto p : pos[j]) {
            int x = p.first.first, y = p.first.second;
            used[i].insert({x, y});
          }
        }
      }
    }

    memset(dp, -1, sizeof dp);
    dp[0][0] = 0;
    for (int i = 0; i < N; i++) {
      for (int j = 0; j < 1 << N; j++) {
        if (dp[i][j] == -1)
          continue;
        int s = dp[i][j];
        for (int k = 0; k < N; k++) {
          if (j >> k & 1)
            continue;
          int ns = s;
          for (auto p : pos[k]) {
            int x = p.first.first, y = p.first.second;
            int point = p.second;
            if (used[j].count({x, y}))
              continue;
            ns += point;
          }
          dp[i + 1][j | (1 << k)] = max(dp[i + 1][j | (1 << k)], ns);
        }
      }
    }

    int ans = 0;
    for (int j = 0; j < 1 << N; j++) {
      ans = max(ans, dp[N][j]);
    }
    cout << ans << endl;
  }
}