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

#include "bits/stdc++.h"
#include <unordered_map>
#include <unordered_set>
#pragma warning(disable : 4996)
using namespace std;
using ld = long double;
template <class T> using Table = vector<vector<T>>;
const ld eps = 1e-9;

struct Dice {
  int tp;
  int bo;
  int no;
  int so;
  int ea;
  int we;
  Dice(const int tp_, const int bo_, const int no_, const int so_,
       const int ea_, const int we_)
      : tp(tp_), bo(bo_), no(no_), so(so_), ea(ea_), we(we_) {}
  Dice(vector<int> pips_) {}
  Dice() {
    tp = 1;
    /*bo = 6;
    no = 2;
    so = 5;
    ea = 3;
    we = 4;*/
  }
  enum R_Way {
    R_Left = 0,
    R_Front = 1,
    R_Right = 2,
    R_Back = 3,

    R_Dummy,
  };
  int rotate(const R_Way way) {
    switch (way) {
    case R_Right: {
      int c = tp;
      tp = we;
      we = bo;
      bo = ea;
      ea = c;
    } break;
    case R_Back: {
      int c = tp;
      tp = so;
      so = bo;
      bo = no;
      no = c;
    } break;
    case R_Left: {
      int c = tp;
      tp = ea;
      ea = bo;
      bo = we;
      we = c;
    } break;
    case R_Front: {
      int c = tp;
      tp = no;
      no = bo;
      bo = so;
      so = c;
    } break;
    default:
      assert(false);
    }
    return tp;
  }
  int rotate(const int way) { return rotate(static_cast<R_Way>(way)); }
  int hash() const { return tp + we * 6 + no * 36; }
};
int geteast(int top, int south) {
  map<pair<int, int>, int> mp;
  mp[make_pair(1, 2)] = 3;
  mp[make_pair(1, 3)] = 5;
  mp[make_pair(2, 3)] = 1;
  mp[make_pair(2, 4)] = 6;
  bool rev = false;
  if (top >= 4) {
    rev = !rev;
    top = 7 - top;
  }
  if (south >= 4) {
    rev = !rev;
    south = 7 - south;
  }
  if (top > south) {
    rev = !rev;
    swap(top, south);
  }
  return mp[make_pair(top, south)];
}

int gettop(int south, int east) { return geteast(south, east); }
int getsouth(int east, int top) { return 7 - geteast(top, east); }
bool operator==(const Dice &l, const Dice &r) { return l.hash() == r.hash(); }

const int dx[4] = {-1, 0, 1, 0};
const int dy[4] = {0, -1, 0, 1};

pair<int, vector<pair<short, short>>>
getmemo(const vector<map<pair<short, short>, short>> &field,
        vector<pair<int, vector<pair<short, short>>>> &memo, bitset<15> &used) {
  if (memo[used.to_ulong()].second.empty()) {
    if (!used.count()) {
      return make_pair(0, vector<pair<short, short>>());
    } else {
      int high_sc = -1;
      vector<pair<short, short>> hi_fi;
      for (int i = 0; i < 15; ++i) {
        if (used[i]) {
          used[i] = false;
          auto pre(getmemo(field, memo, used));
          int sc = pre.first;
          auto pre_fi = pre.second;
          used[i] = true;
          auto new_fi(pre_fi);
          for (auto n_c : field[i]) {
            if (!binary_search(pre_fi.begin(), pre_fi.end(), n_c.first)) {
              sc += n_c.second;
              new_fi.emplace_back(n_c.first);
            }
          }
          if (high_sc < sc) {
            high_sc = sc;

            sort(new_fi.begin(), new_fi.end());
            new_fi.erase(unique(new_fi.begin(), new_fi.end()), new_fi.end());

            hi_fi = new_fi;
          }
        }
      }
      return memo[used.to_ulong()] = make_pair(high_sc, hi_fi);
    }
  } else {
    return memo[used.to_ulong()];
  }
}
int main() {
  while (1) {
    int N;
    cin >> N;
    if (!N)
      break;
    vector<map<pair<short, short>, short>> field(
        N, map<pair<short, short>, short>());
    map<char, short> name;
    name['R'] = 2;
    name['L'] = 0;
    name['B'] = 3;
    name['F'] = 1;
    for (int i = 0; i < N; ++i) {
      map<pair<short, short>, short> mp;
      int x, y;
      cin >> x >> y;
      int l, r, f, b, d, u;
      cin >> l >> r >> f >> b >> d >> u;
      string rot;
      cin >> rot;
      mp[make_pair(x, y)] = d;
      Dice di(u, d, b, f, r, l);

      for (auto c : rot) {
        const int way = name[c];
        x += dx[way];
        y += dy[way];
        di.rotate(way);
        mp[make_pair(x, y)] = di.bo;
      }
      field[i] = mp;
    }
    vector<pair<int, vector<pair<short, short>>>> memo(1 << N);
    bitset<15> bs((1 << N) - 1);
    auto ans = getmemo(field, memo, bs);
    cout << ans.first << endl;
  }

  return 0;
}

Error: TLE

Fixed submission:

#include "bits/stdc++.h"
#include <unordered_map>
#include <unordered_set>
#pragma warning(disable : 4996)
using namespace std;
using ld = long double;
template <class T> using Table = vector<vector<T>>;
const ld eps = 1e-9;

struct Dice {
  int tp;
  int bo;
  int no;
  int so;
  int ea;
  int we;
  Dice(const int tp_, const int bo_, const int no_, const int so_,
       const int ea_, const int we_)
      : tp(tp_), bo(bo_), no(no_), so(so_), ea(ea_), we(we_) {}
  Dice(vector<int> pips_) {}
  Dice() {
    tp = 1;
    /*bo = 6;
    no = 2;
    so = 5;
    ea = 3;
    we = 4;*/
  }
  enum R_Way {
    R_Left = 0,
    R_Front = 1,
    R_Right = 2,
    R_Back = 3,

    R_Dummy,
  };
  int rotate(const R_Way way) {
    switch (way) {
    case R_Right: {
      int c = tp;
      tp = we;
      we = bo;
      bo = ea;
      ea = c;
    } break;
    case R_Back: {
      int c = tp;
      tp = so;
      so = bo;
      bo = no;
      no = c;
    } break;
    case R_Left: {
      int c = tp;
      tp = ea;
      ea = bo;
      bo = we;
      we = c;
    } break;
    case R_Front: {
      int c = tp;
      tp = no;
      no = bo;
      bo = so;
      so = c;
    } break;
    default:
      assert(false);
    }
    return tp;
  }
  int rotate(const int way) { return rotate(static_cast<R_Way>(way)); }
  int hash() const { return tp + we * 6 + no * 36; }
};
int geteast(int top, int south) {
  map<pair<int, int>, int> mp;
  mp[make_pair(1, 2)] = 3;
  mp[make_pair(1, 3)] = 5;
  mp[make_pair(2, 3)] = 1;
  mp[make_pair(2, 4)] = 6;
  bool rev = false;
  if (top >= 4) {
    rev = !rev;
    top = 7 - top;
  }
  if (south >= 4) {
    rev = !rev;
    south = 7 - south;
  }
  if (top > south) {
    rev = !rev;
    swap(top, south);
  }
  return mp[make_pair(top, south)];
}

int gettop(int south, int east) { return geteast(south, east); }
int getsouth(int east, int top) { return 7 - geteast(top, east); }
bool operator==(const Dice &l, const Dice &r) { return l.hash() == r.hash(); }

const int dx[4] = {-1, 0, 1, 0};
const int dy[4] = {0, -1, 0, 1};

pair<int, map<pair<short, short>, short>>
getmemo(const vector<map<pair<short, short>, short>> &field,
        vector<pair<int, map<pair<short, short>, short>>> &memo,
        bitset<15> &used) {
  if (memo[used.to_ulong()].second.empty()) {
    if (!used.count()) {
      return make_pair(0, map<pair<short, short>, short>());
    } else {
      int high_sc = -1;
      map<pair<short, short>, short> hi_fi;
      for (int i = 0; i < 15; ++i) {
        if (used[i]) {
          used[i] = false;
          auto pre(getmemo(field, memo, used));
          int sc = pre.first;
          auto pre_fi = pre.second;
          used[i] = true;
          for (auto n_c : field[i]) {
            if (pre_fi.find(n_c.first) == pre_fi.end()) {
              pre_fi[n_c.first] = n_c.second;
              sc += n_c.second;
            }
          }
          if (high_sc < sc) {
            high_sc = sc;
            hi_fi = pre_fi;
          }
        }
      }
      return memo[used.to_ulong()] = make_pair(high_sc, hi_fi);
    }
  } else {
    return memo[used.to_ulong()];
  }
}
int main() {
  while (1) {
    int N;
    cin >> N;
    if (!N)
      break;
    vector<map<pair<short, short>, short>> field(
        N, map<pair<short, short>, short>());
    map<char, short> name;
    name['R'] = 2;
    name['L'] = 0;
    name['B'] = 3;
    name['F'] = 1;
    for (int i = 0; i < N; ++i) {
      map<pair<short, short>, short> mp;
      int x, y;
      cin >> x >> y;
      int l, r, f, b, d, u;
      cin >> l >> r >> f >> b >> d >> u;
      string rot;
      cin >> rot;
      mp[make_pair(x, y)] = d;
      Dice di(u, d, b, f, r, l);

      for (auto c : rot) {
        const int way = name[c];
        x += dx[way];
        y += dy[way];
        di.rotate(way);
        mp[make_pair(x, y)] = di.bo;
      }
      field[i] = mp;
    }
    vector<pair<int, map<pair<short, short>, short>>> memo(1 << N);
    bitset<15> bs((1 << N) - 1);
    auto ans = getmemo(field, memo, bs);
    cout << ans.first << endl;
  }

  return 0;
}