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

// 基本テンプレート

#include <algorithm>
#include <cassert>
#include <cfloat>
#include <climits>
#include <cmath>
#include <complex>
#include <cstdio>
#include <cstring>
#include <ctime>
#include <deque>
#include <fstream>
#include <functional>
#include <iomanip>
#include <iostream>
#include <limits>
#include <list>
#include <map>
#include <numeric>
#include <queue>
#include <set>
#include <stack>
#include <string>
#include <utility>
#include <vector>
using namespace std;

#define rep(i, a, n) for (int(i) = (a); (i) < (n); (i)++)
#define repq(i, a, n) for (int(i) = (a); (i) <= (n); (i)++)
#define repr(i, a, n) for (int(i) = (a); (i) >= (n); (i)--)
#define debug(...) fprintf(stderr, __VA_ARGS__)
#define int long long int

template <typename T> void chmax(T &a, T b) { a = max(a, b); }
template <typename T> void chmin(T &a, T b) { a = min(a, b); }
template <typename T> void chadd(T &a, T b) { a = a + b; }

typedef pair<int, int> pii;
typedef long long ll;

int dx[] = {0, 0, 1, -1};
int dy[] = {1, -1, 0, 0};
const ll INF = 1001001001001001LL;
const ll MOD = 1000000007LL;

const int S = 4000;
const int N = 5;
using vector2D = vector<vector<int>>;

int base_x[] = {0, 0, 1, 1};
int base_y[] = {0, 1, 0, 1};
vector<vector<int>> cand;

void init_cand() {
  for (int i = 0; i < 4; i++) {
    for (int j = 0; j < 4; j++) {
      for (int k = 0; k < 4; k++) {
        for (int x = 0; x < 4; x++) {
          vector<int> v = {i, j, k, x};
          cand.push_back(v);
        }
      }
    }
  }
}

int get_hash(vector<int> v) {
  int ret = 0;
  for (int i = 0; i < N; i++) {
    ret *= 5;
    ret += v[i];
  }
  return ret;
}

int get_point(vector<int> v) {
  int ret = 0;
  vector<int> pts = {0, 0, 60, 70, 80};
  for (int i = 0; i < N; i++) {
    ret += pts[v[i]];
  }
  return ret;
}

int solve(vector2D board) {
  map<vector<int>, int> dp, swp;
  dp[board[0]] = 0;
  for (int k = 0; k < 4; k++) {
    for (auto e : dp) {
      vector<int> pat = e.first;
      for (auto v : cand) {
        vector<vector<int>> tmp(2, vector<int>(N));
        tmp[0] = pat;
        tmp[1] = board[k + 1];

        for (int i = 0; i < 4; i++) {
          int shift = v[i];
          for (int j = 0; j < 4; j++) {
            int x = base_x[j], y = base_y[j] + i;

            if (tmp[x][y] == 0)
              continue;
            tmp[x][y] = (tmp[x][y] - 1 + shift) % 4 + 1;
          }
        }

        int score = dp[pat] + get_point(tmp[0]);
        if (k == 3)
          score += get_point(tmp[1]);

        vector<int> nxt = tmp[1];
        if (!swp.count(nxt) || swp[nxt] < score) {
          swp[nxt] = score;
        }
      }
    }

    swap(dp, swp);
  }

  int ans = 0;
  for (auto x : dp) {
    chmax(ans, x.second);
  }
  return ans;
}

signed main() {
  init_cand();
  int T;
  cin >> T;
  while (T--) {
    vector2D board(N, vector<int>(N));
    for (int i = 0; i < N; i++) {
      for (int j = 0; j < N; j++) {
        cin >> board[i][j];
      }
    }

    cout << solve(board) << endl;
  }
  return 0;
}


Error: TLE

Fixed submission:

#include <algorithm>
#include <cstdio>
#include <iostream>
#include <map>
#include <unordered_map>
#include <vector>
using namespace std;
map<vector<int>, int> scores;

void init() {
  for (int i = 0; i < 5; i++) {
    for (int j = 0; j < 5; j++) {
      for (int k = 0; k < 5; k++) {
        for (int l = 0; l < 5; l++) {
          for (int m = 0; m < 5; m++) {
            vector<int> pat = {i, j, k, l, m};

            int sum = 0;
            vector<int> pts = {0, 0, 60, 70, 80};

            for (int x = 0; x < 5; x++) {
              sum += pts[pat[x]];
            }

            scores[pat] = sum;
          }
        }
      }
    }
  }
}

int get_hash(vector<int> v) {
  int ret = 0;
  for (int i = 0; i < 5; i++) {
    ret *= 5;
    ret += v[i];
  }
  return ret;
}

const int N = 5;
const int M = 4000;
int board[N][N];
int base_x[] = {0, 0, 1, 1};
int base_y[] = {0, 1, 0, 1};
vector<int> mp(M);

int solve(const vector<int> &pat) {
  int hash = get_hash(pat);
  if (mp[hash] != -1) {
    return mp[hash];
  }

  vector<vector<int>> ary(3, vector<int>(N));
  for (int i = 0; i < N; i++) {
    ary[0][i] = pat[i];
  }
  for (int i = 0; i < 2; i++) {
    for (int j = 0; j < N; j++) {
      int row = i + 3, col = j;
      ary[i + 1][j] = board[row][col];
    }
  }

  int ret = 0;
  for (int bit = 0; bit < (1 << 16); bit++) {
    vector<vector<int>> tmp = ary;

    for (int x = 0; x < 8; x++) {
      int a = (bit >> (2 * x) & 1);
      int b = (bit >> (2 * x + 1) & 1);
      int shift = 2 * a + b;

      int dx = x / 4, dy = x % 4;
      for (int i = 0; i < 4; i++) {
        int p = base_x[i] + dx;
        int q = base_y[i] + dy;

        if (tmp[p][q] == 0)
          continue;
        int new_p = (tmp[p][q] - 1 + shift) % 4 + 1;
        tmp[p][q] = new_p;
      }
    }

    int sum = 0;
    vector<int> pts = {0, 0, 60, 70, 80};
    for (int i = 0; i < 3; i++) {
      sum += scores[tmp[i]];
    }

    ret = max(ret, sum);
  }
  return mp[hash] = ret;
}

int solve_2() {
  int ret = 0;
  vector<vector<int>> ary(3, vector<int>(N));
  for (int i = 0; i < 3; i++) {
    for (int j = 0; j < N; j++) {
      ary[i][j] = board[i][j];
    }
  }

  for (int bit = 0; bit < (1 << 16); bit++) {
    vector<vector<int>> tmp = ary;
    for (int x = 0; x < 8; x++) {
      int a = (bit >> (2 * x) & 1);
      int b = (bit >> (2 * x + 1) & 1);
      int shift = 2 * a + b;

      int dx = x / 4, dy = x % 4;
      for (int i = 0; i < 4; i++) {
        int p = base_x[i] + dx;
        int q = base_y[i] + dy;

        if (tmp[p][q] == 0)
          continue;
        int new_p = (tmp[p][q] - 1 + shift) % 4 + 1;
        tmp[p][q] = new_p;
      }
    }

    // only upper 2-rows
    int sum = 0;
    vector<int> pts = {0, 0, 60, 70, 80};
    for (int i = 0; i < 2; i++) {
      sum += scores[tmp[i]];
    }

    vector<int> vec;
    for (int i = 0; i < N; i++) {
      vec.push_back(tmp[2][i]);
    }

    sum += solve(vec);
    ret = max(ret, sum);
  }

  return ret;
}

int main() {
  init();
  int T;
  scanf(" %d", &T);
  while (T--) {
    fill(mp.begin(), mp.end(), -1);
    for (int i = 0; i < N; i++) {
      for (int j = 0; j < N; j++) {
        scanf(" %d", &board[i][j]);
        // cin >> board[i][j];
      }
    }

    int M = 2;

    /*
    map< vector<int>, int > checked;
    for(int i=0; i<5; i++) {
      for(int j=0; j<5; j++) {
        for(int k=0; k<5; k++) {
          for(int l=0; l<5; l++) {
            for(int m=0; m<5; m++) {
              vector<int> pat = {i, j, k, l, m};

              bool ng = false;
              for(int x=0; x<5; x++) {
                if(board[M][x] == 0 && pat[x] != 0) ng = true;
                if(board[M][x] != 0 && pat[x] == 0) ng = true;
              }

              if(ng) continue;
              if(checked.count(pat)) continue;
              checked[pat]++;

              checked[pat] = solve(pat);
            }
          }
        }
      }
    }
    */

    printf("%d\\n", solve_2());
  }
  return 0;
}