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

//=================================
// Created on: 2018/07/02 20:16:19
//=================================
#pragma GCC optimize("O3")
#pragma GCC target("tune=native")
#pragma GCC target("avx")
#include <bits/stdc++.h>
using namespace std;
int main() {
  int N;
  cin >> N;
  using P = pair<int, int>;
  vector<P> s(N);
  for (int i = 0, H, W; i < N; i++) {
    cin >> H >> W, s[i] = {H, W};
  }
  vector<vector<int>> f(4, vector<int>(4, 0));
  map<char, int> mp;
  mp['R'] = 1, mp['G'] = 2, mp['B'] = 3;
  for (int i = 0; i < 4; i++) {
    string s;
    cin >> s;
    for (int j = 0; j < 4; j++) {
      f[i][j] = mp[s[j]];
    }
  }
  vector<int> memo(1 << 16, -1);
  auto dfs = [&](auto &&self, const int hash) -> int {
    if (hash == 0) {
      return 0;
    }
    if (memo[hash] != -1) {
      return memo[hash];
    }
    int ans = 30;
    for (int i = 0; i < N; i++) {
      const int H = s[i].first, W = s[i].second;
      for (int h = 1 - H; h < 4; h++) {
        for (int w = 1 - W; w < 4; w++) {
          const int hinf = max(h, 0), winf = max(w, 0);
          const int hsup = min(h + H, 4), wsup = min(w + W, 4);
          int ch = -1;
          bool ok = true;
          for (int i = hinf; i < hsup; i++) {
            for (int j = winf; j < wsup; j++) {
              if (hash & (1 << (4 * i + j))) {
                if (ch != -1 and ch != f[i][j]) {
                  ok = false;
                }
                ch = f[i][j];
              }
            }
          }
          if (not ok or ch == -1) {
            continue;
          }
          int h = hash;
          for (int i = hinf; i < hsup; i++) {
            for (int j = winf; j < wsup; j++) {
              h &= ~(1 << (4 * i + j));
            }
          }
          const int sub = self(self, h) + 1;
          ans = min(ans, sub);
        }
      }
    }
    return memo[hash] = ans;
  };
  const int ans = dfs(dfs, (1 << 16) - 1);
  cout << ans << endl;
  return 0;
}


Error: TLE

Fixed submission:

//=================================
// Created on: 2018/07/02 20:16:19
//=================================
#pragma GCC optimize("O3")
#pragma GCC target("tune=native")
#pragma GCC target("avx")
#include <bits/stdc++.h>
using namespace std;
int main() {
  int N;
  cin >> N;
  using P = pair<int, int>;
  vector<P> s(N);
  for (int i = 0, H, W; i < N; i++) {
    cin >> H >> W, s[i] = {H, W};
  }
  vector<vector<int>> f(4, vector<int>(4, 0));
  map<char, int> mp;
  mp['R'] = 1, mp['G'] = 2, mp['B'] = 3;
  for (int i = 0; i < 4; i++) {
    string s;
    cin >> s;
    for (int j = 0; j < 4; j++) {
      f[i][j] = mp[s[j]];
    }
  }
  vector<int> memo(1 << 16, -1);
  auto dfs = [&](auto &&self, const int hash,
                 const vector<vector<int>> &f) -> int {
    if (hash == 0) {
      return 0;
    }
    if (memo[hash] != -1) {
      return memo[hash];
    }
    int ans = 30;
    for (int i = 0; i < N; i++) {
      const int H = s[i].first, W = s[i].second;
      for (int h = 1 - H; h < 4; h++) {
        for (int w = 1 - W; w < 4; w++) {
          const int hinf = max(h, 0), winf = max(w, 0);
          const int hsup = min(h + H, 4), wsup = min(w + W, 4);
          int ch = -1;
          bool ok = true;
          for (int i = hinf; i < hsup; i++) {
            for (int j = winf; j < wsup; j++) {
              if (f[i][j] != 0) {
                if (ch != -1 and ch != f[i][j]) {
                  ok = false;
                }
                ch = f[i][j];
              }
            }
          }
          if (not ok or ch == -1) {
            continue;
          }
          auto newf = f;
          int h = hash;
          for (int i = hinf; i < hsup; i++) {
            for (int j = winf; j < wsup; j++) {
              newf[i][j] = 0;
              h &= ~(1 << (4 * i + j));
            }
          }
          const int sub = self(self, h, newf) + 1;
          ans = min(ans, sub);
        }
      }
    }
    return memo[hash] = ans;
  };
  const int ans = dfs(dfs, (1 << 16) - 1, f);
  cout << ans << endl;
  return 0;
}