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

#include <bits/stdc++.h>

using namespace std;

#define int long long
#define F first
#define S second
#define all(v) (v).begin(), (v).end()
#define rep(i, n) for (int i = 0; i < (int)(n); i++)
#define reps(i, f, n) for (int i = (int)(f); i < (int)(n); i++)
#define each(a, b) for (auto &a : b)

typedef pair<int, int> P;

const int inf = 1LL << 55;

#define UP 0
#define DOWN 1
#define FORE 2
#define BACK 3
#define RIGHT 4
#define LEFT 5

struct Dice {
  int face[6];
  Dice() {}
  Dice(int up, int down, int fore, int back, int right, int left) {
    face[UP] = up;
    face[DOWN] = down;
    face[FORE] = fore;
    face[BACK] = back;
    face[RIGHT] = right;
    face[LEFT] = left;
  }
  void roll(int a, int b, int c, int d) {
    swap(face[a], face[c]);
    swap(face[b], face[d]);
    swap(face[c], face[d]);
  }
  void roll2fore() { roll(FORE, BACK, UP, DOWN); }
  void roll2back() { roll(BACK, FORE, UP, DOWN); }
  void roll2right() { roll(RIGHT, LEFT, UP, DOWN); }
  void roll2left() { roll(LEFT, RIGHT, UP, DOWN); }
  void rotate_clockwise() { roll(FORE, BACK, RIGHT, LEFT); }
  void rotate_counterclockwise() { roll(FORE, BACK, LEFT, RIGHT); }
  void print_face() {
    printf("UP   : %d\\n", face[UP]);
    printf("DOWN : %d\\n", face[DOWN]);
    printf("FORE : %d\\n", face[FORE]);
    printf("BACK : %d\\n", face[BACK]);
    printf("RIGHT: %d\\n", face[RIGHT]);
    printf("LEFT : %d\\n", face[LEFT]);
  }
};

int N;
vector<int> sx, sy;
vector<Dice> dice;
vector<string> rot;
vector<vector<P>> ftpts;
vector<vector<int>> stamp;

int dp[1 << 16];
map<P, bool> used;

string dir = "LRFB";
int dx[] = {-1, 1, 0, 0};
int dy[] = {0, 0, -1, 1};

int solve(int bit) {
  if (bit == (1 << N) - 1)
    return 0;
  int &ret = dp[bit];
  if (~ret)
    return ret;

  ret = 0;
  for (int i = 0; i < N; i++) {
    if ((bit >> i) & 1)
      continue;
    int sum = 0;
    vector<P> reset;
    for (int j = 0; j < ftpts[i].size(); j++) {
      if (used[ftpts[i][j]])
        continue;
      used[ftpts[i][j]] = true;
      sum += stamp[i][j];
      reset.push_back(ftpts[i][j]);
    }
    ret = max(ret, solve(bit | (1 << i)) + sum);
    for (int j = 0; j < reset.size(); j++) {
      used[reset[j]] = false;
    }
  }

  return ret;
}

void init() {
  sx.clear();
  sx.resize(N);
  sy.clear();
  sy.resize(N);
  dice.clear();
  dice.resize(N);
  rot.clear();
  rot.resize(N);

  for (int i = 0; i < N; i++) {
    cin >> sx[i] >> sy[i];
    int l, r, f, b, d, u;
    cin >> l >> r >> f >> b >> d >> u;
    dice[i] = Dice(u, d, f, b, r, l);
    cin >> rot[i];
  }
}

void footprints() {
  ftpts.clear();
  ftpts.resize(N);
  stamp.clear();
  stamp.resize(N);
  for (int i = 0; i < N; i++) {
    Dice die = dice[i];
    int x = sx[i], y = sy[i];
    ftpts[i].push_back(P(x, y));
    stamp[i].push_back(die.face[DOWN]);
    for (int j = 0; j < rot[i].size(); j++) {
      int d = dir.find(rot[i][j]);
      x += dx[d], y += dy[d];
      switch (rot[i][j]) {
      case 'L':
        die.roll2left();
        break;
      case 'R':
        die.roll2right();
        break;
      case 'F':
        die.roll2fore();
        break;
      case 'B':
        die.roll2back();
        break;
      }
      ftpts[i].push_back(P(x, y));
      stamp[i].push_back(die.face[DOWN]);
    }
    reverse(all(ftpts[i]));
    reverse(all(stamp[i]));
  }
}

signed main() {
  cin.tie(0);
  ios_base::sync_with_stdio(0);
  cout << fixed << setprecision(12);

  while (cin >> N, N) {
    init();
    footprints();
    memset(dp, -1, sizeof(dp));
    used.clear();
    cout << solve(0) << endl;
  }
  return 0;
}

Error: TLE

Fixed submission:

#include <bits/stdc++.h>

using namespace std;

#define int long long
#define F first
#define S second
#define all(v) (v).begin(), (v).end()
#define rep(i, n) for (int i = 0; i < (int)(n); i++)
#define reps(i, f, n) for (int i = (int)(f); i < (int)(n); i++)
#define each(a, b) for (auto &a : b)

typedef pair<int, int> P;

const int inf = 1LL << 55;

#define UP 0
#define DOWN 1
#define FORE 2
#define BACK 3
#define RIGHT 4
#define LEFT 5

struct Dice {
  int face[6];
  Dice() {}
  Dice(int up, int down, int fore, int back, int right, int left) {
    face[UP] = up;
    face[DOWN] = down;
    face[FORE] = fore;
    face[BACK] = back;
    face[RIGHT] = right;
    face[LEFT] = left;
  }
  void roll(int a, int b, int c, int d) {
    swap(face[a], face[c]);
    swap(face[b], face[d]);
    swap(face[c], face[d]);
  }
  void roll2fore() { roll(FORE, BACK, UP, DOWN); }
  void roll2back() { roll(BACK, FORE, UP, DOWN); }
  void roll2right() { roll(RIGHT, LEFT, UP, DOWN); }
  void roll2left() { roll(LEFT, RIGHT, UP, DOWN); }
  void rotate_clockwise() { roll(FORE, BACK, RIGHT, LEFT); }
  void rotate_counterclockwise() { roll(FORE, BACK, LEFT, RIGHT); }
  void print_face() {
    printf("UP   : %d\\n", face[UP]);
    printf("DOWN : %d\\n", face[DOWN]);
    printf("FORE : %d\\n", face[FORE]);
    printf("BACK : %d\\n", face[BACK]);
    printf("RIGHT: %d\\n", face[RIGHT]);
    printf("LEFT : %d\\n", face[LEFT]);
  }
};

int N;
vector<int> x, y;
vector<Dice> dice;
vector<string> rot;

int dp[1 << 16];
map<P, bool> used;

string dir = "LRFB";
int dx[] = {-1, 1, 0, 0};
int dy[] = {0, 0, -1, 1};

int solve(int bit) {
  if (bit == (1 << N) - 1)
    return 0;
  int &ret = dp[bit];
  if (~ret)
    return ret;

  ret = 0;
  for (int i = 0; i < N; i++) {
    if ((bit >> i) & 1)
      continue;
    map<P, int> me;
    Dice die = dice[i];
    int nx = x[i], ny = y[i];
    int sum = die.face[DOWN];
    used[P(ny, nx)] = true;
    me[P(ny, nx)] = die.face[DOWN];
    for (int j = 0; j < rot[i].size(); j++) {
      int d = dir.find(rot[i][j]);
      nx += dx[d], ny += dy[d];
      switch (rot[i][j]) {
      case 'L':
        die.roll2left();
        break;
      case 'R':
        die.roll2right();
        break;
      case 'F':
        die.roll2fore();
        break;
      case 'B':
        die.roll2back();
        break;
      }
      if (used[P(ny, nx)] && me.count(P(ny, nx)) == 0)
        continue;
      sum += die.face[DOWN] - me[P(ny, nx)];
      me[P(ny, nx)] = die.face[DOWN] - me[P(ny, nx)];
      used[P(ny, nx)] = true;
    }
    ret = max(ret, solve(bit | (1 << i)) + sum);
    die = dice[i];
    nx = x[i], ny = y[i];
    used[P(ny, nx)] = false;
    for (int j = 0; j < rot[i].size(); j++) {
      int d = dir.find(rot[i][j]);
      nx += dx[d], ny += dy[d];
      switch (rot[i][j]) {
      case 'L':
        die.roll2left();
        break;
      case 'R':
        die.roll2right();
        break;
      case 'F':
        die.roll2fore();
        break;
      case 'B':
        die.roll2back();
        break;
      }
      if (used[P(ny, nx)] && me.count(P(ny, nx)) == 0)
        continue;
      used[P(ny, nx)] = false;
    }
  }

  return ret;
}

signed main() {
  cin.tie(0);
  ios_base::sync_with_stdio(0);
  cout << fixed << setprecision(12);

  while (cin >> N, N) {
    x.clear();
    x.resize(N);
    y.clear();
    y.resize(N);
    dice.clear();
    dice.resize(N);
    rot.clear();
    rot.resize(N);
    for (int i = 0; i < N; i++) {
      cin >> x[i] >> y[i];
      int l, r, f, b, d, u;
      cin >> l >> r >> f >> b >> d >> u;
      dice[i] = Dice(u, d, f, b, r, l);
      cin >> rot[i];
    }
    used.clear();
    memset(dp, -1, sizeof(dp));
    cout << solve(0) << endl;
  }
  return 0;
}