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

#include <bits/stdc++.h>
#define N 16
using namespace std;
const int mod = (1e9) + 7;
const double EPS = 1e-8;
const double PI = 6.0 * asin(0.5);
template <class T> T Max(T &a, T b) { return a = max(a, b); }
template <class T> T Min(T &a, T b) { return a = min(a, b); }

const int TOP = 0, FRONT = 1, LEFT = 2, RIGHT = 3, BACK = 4, BOTTOM = 5;
class Dice {
public:
  int val[6];
  Dice() {
    for (int i = 0; i < 6; i++)
      val[i] = i;
  }
  Dice(int val[6]) {
    for (int i = 0; i < 6; i++)
      this->val[i] = val[i];
  }
  Dice(int l, int r, int f, int b, int d, int u) {
    val[LEFT] = l, val[RIGHT] = r;
    val[FRONT] = f, val[BACK] = b;
    val[BOTTOM] = d, val[TOP] = u;
  }
  void rot(string s) {
    if (s == "N" || s == "B")
      rotN();
    else if (s == "S" || s == "F")
      rotS();
    else if (s == "E" || s == "R")
      rotE();
    else if (s == "W" || s == "L")
      rotW();
    else if (s == "CW")
      rotCW();
    else if (s == "CCW")
      rotCCW();
    else
      assert(!"rot error");
  }

  //?\\\\?????¢??????
  void rotN() {
    swap(val[TOP], val[FRONT]);
    swap(val[FRONT], val[BOTTOM]);
    swap(val[BOTTOM], val[BACK]);
  }

  //???????????¢??????
  void rotS() {
    // rotN(),rotN(),rotN();
    swap(val[TOP], val[BACK]);
    swap(val[BACK], val[BOTTOM]);
    swap(val[BOTTOM], val[FRONT]);
  }

  //????????¢??????
  void rotE() {
    swap(val[TOP], val[LEFT]);
    swap(val[LEFT], val[BOTTOM]);
    swap(val[BOTTOM], val[RIGHT]);
  }

  //????????¢??????
  void rotW() {
    // rotE(),rotE(),rotE();
    swap(val[TOP], val[RIGHT]);
    swap(val[RIGHT], val[BOTTOM]);
    swap(val[BOTTOM], val[LEFT]);
  }

  //???????????????????¨????????????????
  void rotCW() {
    swap(val[FRONT], val[RIGHT]);
    swap(val[RIGHT], val[BACK]);
    swap(val[BACK], val[LEFT]);
  }

  //??????????????????????¨???????????????????
  void rotCCW() {
    // rotCW(),rotCW(),rotCW();
    swap(val[FRONT], val[LEFT]);
    swap(val[LEFT], val[BACK]);
    swap(val[BACK], val[RIGHT]);
  }
};

int n;
struct dat {
  int x, y;
  Dice d;
};
typedef pair<short, short> P;
typedef map<P, int> M;
typedef set<P> S;

M dice[N];
M getMove(int x, int y, Dice d, string rot) {
  static int dx[1 << 8] = {}, dy[1 << 8] = {};
  dx['L'] = -1, dx['R'] = 1, dy['F'] = -1, dy['B'] = 1;
  M res;
  res[P(x, y)] = d.val[BOTTOM];
  for (char ch : rot) {
    x += dx[(int)ch], y += dy[(int)ch];
    d.rot(string(1, ch));
    res[P(x, y)] = d.val[BOTTOM];
  }
  return res;
}

int getScore(int idx, S &used) {
  int res = 0;
  for (pair<P, int> const &p : dice[idx])
    if (!used.count(p.first))
      res += p.second;
  return res;
}

S getUsed(int idx, S used) {
  for (pair<P, int> const &p : dice[idx])
    used.insert(p.first);
  return used;
}

int DP() {
  S used[1 << N];
  int dp[1 << N] = {};
  for (int bit = 0; bit < (1 << n); bit++)
    for (int i = 0; i < n; i++) {
      if (bit >> i & 1)
        continue;
      int nbit = bit | (1 << i);
      int nscore = dp[bit] + getScore(i, used[bit]);
      Max(dp[nbit], nscore);
      if (used[nbit].empty())
        used[nbit] = getUsed(i, used[bit]);
    }
  return dp[(1 << n) - 1];
}

signed main() {
  while (cin >> n, n) {
    for (int i = 0; i < n; i++) {
      int x, y;
      int l, r, f, b, d, u;
      string rot;
      cin >> x >> y >> l >> r >> f >> b >> d >> u >> rot;
      dice[i] = getMove(x, y, Dice(l, r, f, b, d, u), rot);
    }
    cout << DP() << endl;
  }
  return 0;
}

Error: TLE

Fixed submission:

#include <bits/stdc++.h>
#define N 16
using namespace std;
const int mod = (1e9) + 7;
const double EPS = 1e-8;
const double PI = 6.0 * asin(0.5);
template <class T> T Max(T &a, T b) { return a = max(a, b); }
template <class T> T Min(T &a, T b) { return a = min(a, b); }

const int TOP = 0, FRONT = 1, LEFT = 2, RIGHT = 3, BACK = 4, BOTTOM = 5;
class Dice {
public:
  int val[6];
  Dice() {
    for (int i = 0; i < 6; i++)
      val[i] = i;
  }
  Dice(int val[6]) {
    for (int i = 0; i < 6; i++)
      this->val[i] = val[i];
  }
  Dice(int l, int r, int f, int b, int d, int u) {
    val[LEFT] = l, val[RIGHT] = r;
    val[FRONT] = f, val[BACK] = b;
    val[BOTTOM] = d, val[TOP] = u;
  }
  void rot(string s) {
    if (s == "N" || s == "B")
      rotN();
    else if (s == "S" || s == "F")
      rotS();
    else if (s == "E" || s == "R")
      rotE();
    else if (s == "W" || s == "L")
      rotW();
    else if (s == "CW")
      rotCW();
    else if (s == "CCW")
      rotCCW();
    else
      assert(!"rot error");
  }

  //?\\\\?????¢??????
  void rotN() {
    swap(val[TOP], val[FRONT]);
    swap(val[FRONT], val[BOTTOM]);
    swap(val[BOTTOM], val[BACK]);
  }

  //???????????¢??????
  void rotS() {
    // rotN(),rotN(),rotN();
    swap(val[TOP], val[BACK]);
    swap(val[BACK], val[BOTTOM]);
    swap(val[BOTTOM], val[FRONT]);
  }

  //????????¢??????
  void rotE() {
    swap(val[TOP], val[LEFT]);
    swap(val[LEFT], val[BOTTOM]);
    swap(val[BOTTOM], val[RIGHT]);
  }

  //????????¢??????
  void rotW() {
    // rotE(),rotE(),rotE();
    swap(val[TOP], val[RIGHT]);
    swap(val[RIGHT], val[BOTTOM]);
    swap(val[BOTTOM], val[LEFT]);
  }

  //???????????????????¨????????????????
  void rotCW() {
    swap(val[FRONT], val[RIGHT]);
    swap(val[RIGHT], val[BACK]);
    swap(val[BACK], val[LEFT]);
  }

  //??????????????????????¨???????????????????
  void rotCCW() {
    // rotCW(),rotCW(),rotCW();
    swap(val[FRONT], val[LEFT]);
    swap(val[LEFT], val[BACK]);
    swap(val[BACK], val[RIGHT]);
  }
};

int n;
struct dat {
  int x, y;
  Dice d;
};
typedef pair<short, short> P;
typedef map<P, int> M;
typedef set<P> S;

M dice[N];
M getMove(int x, int y, Dice d, string rot) {
  static int dx[1 << 8] = {}, dy[1 << 8] = {};
  dx['L'] = -1, dx['R'] = 1, dy['F'] = -1, dy['B'] = 1;
  M res;
  res[P(x, y)] = d.val[BOTTOM];
  for (char ch : rot) {
    x += dx[(int)ch], y += dy[(int)ch];
    d.rot(string(1, ch));
    res[P(x, y)] = d.val[BOTTOM];
  }
  return res;
}

pair<S, int> getNx(int idx, S used, int score) {
  for (pair<P, int> const &p : dice[idx]) {
    if (used.count(p.first))
      continue;
    used.insert(p.first);
    score += p.second;
  }
  return make_pair(used, score);
}

int DP() {
  map<S, int> dp[1 << N];
  int res = 0;
  dp[0][S()] = 0;
  for (int bit = 0; bit < (1 << n); dp[bit].clear(), bit++) {
    for (int i = 0; i < n; i++) {
      if (bit >> i & 1)
        continue;
      for (pair<S, int> const &p : dp[bit]) {
        int nbit = bit | (1 << i);
        pair<S, int> nx = getNx(i, p.first, p.second);
        Max(dp[nbit][nx.first], nx.second);
        Max(res, nx.second);
      }
    }
  }

  return res;
}

signed main() {
  while (cin >> n, n) {
    for (int i = 0; i < n; i++) {
      int x, y;
      int l, r, f, b, d, u;
      string rot;
      cin >> x >> y >> l >> r >> f >> b >> d >> u >> rot;
      dice[i] = getMove(x, y, Dice(l, r, f, b, d, u), rot);
    }
    cout << DP() << endl;
  }
  return 0;
}