Problem p01806 (C++)

Buggy submission (status: Time Limit Exceeded):
#include <bits/stdc++.h>

using namespace std;

struct Dice {
  int x, y;
  int l, r, f, b, d, u;

  void RollF() {
    --y;
    int buff = d;
    d = f;
    f = u;
    u = b;
    b = buff;
  }

  void RollB() {
    ++y;
    int buff = d;
    d = b;
    b = u;
    u = f;
    f = buff;
  }

  void RollL() {
    --x;
    int buff = d;
    d = l;
    l = u;
    u = r;
    r = buff;
  }

  void RollR() {
    ++x;
    int buff = d;
    d = r;
    r = u;
    u = l;
    l = buff;
  }
};

int N;
Dice dice[15];
string rot[15];
int dp[1 << 15];
int v[2100][2100], buff[2100][2100];

void Roll(Dice &obj, char c) {
  switch (c) {
  case 'L':
    obj.RollL();
    return;
  case 'R':
    obj.RollR();
    return;
  case 'B':
    obj.RollB();
    return;
  case 'F':
    obj.RollF();
    return;
  default:
    return;
  }
}

int AddDice(int idx) {
  int ret = 0;
  Dice obj = dice[idx];
  for (char c : rot[idx]) {
    Roll(obj, c);
    if (v[obj.y][obj.x] == -1) {
      v[obj.y][obj.x] = idx;
      buff[obj.y][obj.x] = obj.d;
      ret += obj.d;
    } else if (v[obj.y][obj.x] == idx) {
      ret -= buff[obj.y][obj.x];
      ret += obj.d;
      buff[obj.y][obj.x] = obj.d;
    }
  }
  return (ret);
}

void DeleteDice(int idx) {
  Dice obj = dice[idx];
  for (char c : rot[idx]) {
    Roll(obj, c);
    if (v[obj.y][obj.x] == idx) {
      v[obj.y][obj.x] = -1;
    }
  }
}

int rec(int bit) {
  if (bit == (1 << N) - 1)
    return (0);
  if (~dp[bit])
    return (dp[bit]);
  int ret = 0;
  for (int i = 0; i < N; i++) {
    if ((bit >> i) & 1)
      continue;
    int get = AddDice(i);
    ret = max(ret, rec(bit | (1 << i)) + get);
    DeleteDice(i);
  }
  return (ret);
}

int main() {
  memset(v, -1, sizeof(v));
  while (cin >> N, N) {
    for (int i = 0; i < N; ++i) {
      cin >> dice[i].x >> dice[i].y;
      cin >> dice[i].l >> dice[i].r >> dice[i].f >> dice[i].b >> dice[i].d >>
          dice[i].u;
      cin >> rot[i];
      rot[i] = "~" + rot[i];
      dice[i].x += 1050, dice[i].y += 1050;
    }
    memset(dp, -1, sizeof(dp));
    cout << rec(0) << endl;
  }
}

Fixed submission:
#include <bits/stdc++.h>

using namespace std;

struct Dice {
  int x, y;
  int l, r, f, b, d, u;

  void RollF() {
    --y;
    int buff = d;
    d = f;
    f = u;
    u = b;
    b = buff;
  }

  void RollB() {
    ++y;
    int buff = d;
    d = b;
    b = u;
    u = f;
    f = buff;
  }

  void RollL() {
    --x;
    int buff = d;
    d = l;
    l = u;
    u = r;
    r = buff;
  }

  void RollR() {
    ++x;
    int buff = d;
    d = r;
    r = u;
    u = l;
    l = buff;
  }
};

int N;
Dice dice[15];
string rot[15];
int dp[1 << 15];
int v[2100][2100], buff[2100][2100];

void Roll(Dice &obj, char c) {
  switch (c) {
  case 'L':
    obj.RollL();
    return;
  case 'R':
    obj.RollR();
    return;
  case 'B':
    obj.RollB();
    return;
  case 'F':
    obj.RollF();
    return;
  default:
    return;
  }
}

int AddDice(int idx) {
  int ret = 0;
  Dice obj = dice[idx];
  for (char c : rot[idx]) {
    Roll(obj, c);
    if (v[obj.y][obj.x] == -1) {
      v[obj.y][obj.x] = idx;
      buff[obj.y][obj.x] = obj.d;
      ret += obj.d;
    } else if (v[obj.y][obj.x] == idx) {
      ret -= buff[obj.y][obj.x];
      ret += obj.d;
      buff[obj.y][obj.x] = obj.d;
    }
  }
  return (ret);
}

void DeleteDice(int idx) {
  Dice obj = dice[idx];
  for (char c : rot[idx]) {
    Roll(obj, c);
    if (v[obj.y][obj.x] == idx) {
      v[obj.y][obj.x] = -1;
    }
  }
}

int rec(int bit) {
  if (bit == (1 << N) - 1)
    return (0);
  if (~dp[bit])
    return (dp[bit]);
  int ret = 0;
  for (int i = 0; i < N; i++) {
    if ((bit >> i) & 1)
      continue;
    int get = AddDice(i);
    ret = max(ret, rec(bit | (1 << i)) + get);
    DeleteDice(i);
  }
  return (dp[bit] = ret);
}

int main() {
  memset(v, -1, sizeof(v));
  while (cin >> N, N) {
    for (int i = 0; i < N; ++i) {
      cin >> dice[i].x >> dice[i].y;
      cin >> dice[i].l >> dice[i].r >> dice[i].f >> dice[i].b >> dice[i].d >>
          dice[i].u;
      cin >> rot[i];
      rot[i] = "~" + rot[i];
      dice[i].x += 1050, dice[i].y += 1050;
    }
    memset(dp, -1, sizeof(dp));
    cout << rec(0) << endl;
  }
}