Problem p01806 (C++) — buggy submission, verdict: Time Limit Exceeded

#include <bits/stdc++.h>
using namespace std;
struct Dice {
  int y, x;
  int s[6];
  Dice() {}
  void roll(char c) {
    // the view from above
    //  N
    // W E
    //  S
    // s[0]:top
    // s[1]:south
    // s[2]:east
    // s[3]:west
    // s[4]:north
    // s[5]:bottom
    int b;
    if (c == 'R') {
      x++;
      b = s[0];
      s[0] = s[3];
      s[3] = s[5];
      s[5] = s[2];
      s[2] = b;
    }
    if (c == 'L') {
      x--;
      b = s[0];
      s[0] = s[2];
      s[2] = s[5];
      s[5] = s[3];
      s[3] = b;
    }
    if (c == 'B') {
      y++;
      b = s[0];
      s[0] = s[1];
      s[1] = s[5];
      s[5] = s[4];
      s[4] = b;
    }
    if (c == 'F') {
      y--;
      b = s[0];
      s[0] = s[4];
      s[4] = s[5];
      s[5] = s[1];
      s[1] = b;
    }
  }
  int top() { return s[0]; }
  int bottom() { return s[5]; }
};
typedef pair<int, int> P;
int p2i(P p) { return (p.first + 1500) * 3000 + (p.second + 1500); }
unordered_set<int> used;
int memo[1 << 16];
int n;
Dice ds[16];
string rot[16];
int dfs(int b) {
  if (~memo[b])
    return memo[b];
  int res = 0;
  for (int i = 0; i < n; i++) {
    if ((b >> i) & 1)
      continue;
    unordered_map<int, int> v;
    int tmp = 0;
    Dice d = ds[i];
    for (int j = 0; j < (int)rot[i].size(); j++) {
      if (v.count(p2i(P(d.y, d.x))) || !used.count(p2i(P(d.y, d.x)))) {
        // cout<<tmp<<" "<<d.bottom()<<endl;
        tmp += d.bottom();
        if (v.count(p2i(P(d.y, d.x))))
          tmp -= v[p2i(P(d.y, d.x))];
        v[p2i(P(d.y, d.x))] = d.bottom();
        used.insert(p2i(P(d.y, d.x)));
      }
      // cout<<d.y<<" "<<d.x<<":"<<tmp<<" "<<d.bottom()<<endl;
      d.roll(rot[i][j]);
    }
    res = max(res, dfs(b + (1 << i)) + tmp);
    for (auto j : v)
      used.erase(j.first);
  }
  // cout<<b<<" "<<res<<endl;
  return memo[b] = res;
}
signed main() {
  while (cin >> n, n) {
    for (int i = 0; i < n; i++) {
      cin >> ds[i].x >> ds[i].y;
      cin >> ds[i].s[3] >> ds[i].s[2] >> ds[i].s[1];
      cin >> ds[i].s[4] >> ds[i].s[5] >> ds[i].s[0];
      cin >> rot[i];
      rot[i] += "$"; // guard
    }
    used.clear();
    memset(memo, -1, sizeof(memo));
    cout << dfs(0) << endl;
  }
  return 0;
}

Error: TLE

Fixed submission:

#include <bits/stdc++.h>
using namespace std;
struct Dice {
  int y, x;
  int s[6];
  Dice() {}
  void roll(char c) {
    // the view from above
    //  N
    // W E
    //  S
    // s[0]:top
    // s[1]:south
    // s[2]:east
    // s[3]:west
    // s[4]:north
    // s[5]:bottom
    int b;
    if (c == 'R') {
      x++;
      b = s[0];
      s[0] = s[3];
      s[3] = s[5];
      s[5] = s[2];
      s[2] = b;
    }
    if (c == 'L') {
      x--;
      b = s[0];
      s[0] = s[2];
      s[2] = s[5];
      s[5] = s[3];
      s[3] = b;
    }
    if (c == 'B') {
      y++;
      b = s[0];
      s[0] = s[1];
      s[1] = s[5];
      s[5] = s[4];
      s[4] = b;
    }
    if (c == 'F') {
      y--;
      b = s[0];
      s[0] = s[4];
      s[4] = s[5];
      s[5] = s[1];
      s[1] = b;
    }
  }
  int top() { return s[0]; }
  int bottom() { return s[5]; }
};
typedef pair<int, int> P;
set<P> used;
int memo[1 << 16];
int n;
Dice ds[16];
string rot[16];
int dfs(int b) {
  if (~memo[b])
    return memo[b];
  int res = 0;
  for (int i = 0; i < n; i++) {
    if ((b >> i) & 1)
      continue;
    map<P, int> v;
    int tmp = 0;
    Dice d = ds[i];
    for (int j = 0; j < (int)rot[i].size(); j++) {
      if (v.count(P(d.y, d.x)) || !used.count(P(d.y, d.x))) {
        // cout<<tmp<<" "<<d.bottom()<<endl;
        tmp += d.bottom();
        if (v.count(P(d.y, d.x)))
          tmp -= v[P(d.y, d.x)];
        v[P(d.y, d.x)] = d.bottom();
        used.insert(P(d.y, d.x));
      }
      // cout<<d.y<<" "<<d.x<<":"<<tmp<<" "<<d.bottom()<<endl;
      d.roll(rot[i][j]);
    }
    res = max(res, dfs(b + (1 << i)) + tmp);
    for (auto j : v)
      used.erase(j.first);
  }
  // cout<<b<<" "<<res<<endl;
  return memo[b] = res;
}
signed main() {
  while (cin >> n, n) {
    for (int i = 0; i < n; i++) {
      cin >> ds[i].x >> ds[i].y;
      cin >> ds[i].s[3] >> ds[i].s[2] >> ds[i].s[1];
      cin >> ds[i].s[4] >> ds[i].s[5] >> ds[i].s[0];
      cin >> rot[i];
      rot[i] += "$"; // guard
    }
    used.clear();
    memset(memo, -1, sizeof(memo));
    cout << dfs(0) << endl;
  }
  return 0;
}