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

#include <algorithm>
#include <assert.h>
#include <bitset>
#include <cmath>
#include <complex>
#include <cstdlib>
#include <ctime>
#include <fstream>
#include <functional>
#include <iostream>
#include <map>
#include <queue>
#include <set>
#include <stack>
#include <string>
#include <unordered_map>
#include <vector>
using namespace std;
typedef long long ll;
typedef vector<ll> vl;
typedef vector<vl> vvl;
typedef vector<char> vc;
typedef vector<string> vs;
typedef vector<bool> vb;
typedef vector<double> vd;
typedef pair<ll, ll> P;
typedef pair<int, int> pii;
typedef vector<P> vpl;
typedef tuple<ll, ll, ll> tapu;
#define rep(i, n) for (int i = 0; i < (n); i++)
#define REP(i, a, b) for (int i = (a); i < (b); i++)
#define all(x) (x).begin(), (x).end()
#define rall(x) (x).rbegin(), (x).rend()
const int inf = 1 << 30;
const ll linf = 1LL << 62;
const int MAX = 510000;
ll dy[8] = {1, -1, 0, 0, 1, -1, 1, -1};
ll dx[8] = {0, 0, 1, -1, 1, -1, -1, 1};
const double pi = acos(-1);
const double eps = 1e-7;
template <typename T1, typename T2> inline bool chmin(T1 &a, T2 b) {
  if (a > b) {
    a = b;
    return true;
  } else
    return false;
}
template <typename T1, typename T2> inline bool chmax(T1 &a, T2 b) {
  if (a < b) {
    a = b;
    return true;
  } else
    return false;
}
template <typename T> inline void print(T &a) {
  rep(i, a.size()) cout << a[i] << " ";
  cout << "\\n";
}
template <typename T1, typename T2> inline void print2(T1 a, T2 b) {
  cout << a << " " << b << "\\n";
}
template <typename T1, typename T2, typename T3>
inline void print3(T1 a, T2 b, T3 c) {
  cout << a << " " << b << " " << c << "\\n";
}
ll pcount(ll x) { return __builtin_popcountll(x); }
const int mod = 1e9 + 7;
// const int mod = 998244353;

int dp[2020][2020];
int mx2[2020];

int main() {
  int n;
  cin >> n;
  int N = 3 * n;
  vector<int> a(N);
  rep(i, N) cin >> a[i];
  rep(i, n + 1) rep(j, n + 1) dp[i][j] = -inf;
  rep(i, n + 1) mx2[i] = -inf;
  int mx = -inf;
  rep(i, 5) {
    rep(j, i) {
      int m = -1;
      int ad = 1;
      rep(k, 5) {
        if (k == i || k == j)
          continue;
        if (m == -1)
          m = a[k];
        else {
          if (m != a[k]) {
            ad = 0;
            break;
          }
        }
      }
      chmax(dp[a[i]][a[j]], ad);
      chmax(dp[a[j]][a[i]], ad);
      chmax(mx2[a[i]], dp[a[i]][a[j]]);
      chmax(mx2[a[j]], dp[a[j]][a[i]]);
      chmax(mx, dp[a[i]][a[j]]);
    }
  }
  int tmp = 0;
  REP(i, 1, n - 1) {
    int id = i * 3;
    vector<int> v(3);
    rep(j, 3) v[j] = a[id + 2 + j];
    sort(all(v));
    if (v[0] == v[1] && v[1] == v[2]) {
      tmp++;
      continue;
    }
    map<pii, int> mp;
    if (v[0] == v[1] || v[1] == v[2]) {
      int rest;
      if (v[0] == v[1])
        rest = v[2];
      else
        rest = v[0];
      REP(j, 1, n + 1) {
        if (mp.find({j, rest}) == mp.end())
          mp[{j, rest}] = dp[j][v[1]] + 1;
        else
          chmax(mp[{j, rest}], dp[j][v[1]] + 1);
      }
    }
    rep(j, 3) {
      vector<int> u;
      rep(k, 3) {
        if (j == k)
          continue;
        u.push_back(v[k]);
      }
      if (mp.find({u[0], u[1]}) != mp.end()) {
        chmax(mp[{u[0], u[1]}], dp[v[j]][v[j]] + 1);
      } else {
        mp[{u[0], u[1]}] = dp[v[j]][v[j]] + 1;
      }
      chmax(mp[{u[0], u[1]}], mx);
    }
    REP(j, 1, n + 1) {
      rep(k, 3) {
        if (mp.find({j, v[k]}) == mp.end())
          mp[{j, v[k]}] = mx2[j];
        else
          chmax(mp[{j, v[k]}], mx2[j]);
      }
    }
    for (auto j : mp) {
      chmax(dp[j.first.first][j.first.second], j.second);
      chmax(dp[j.first.second][j.first.first], j.second);
      chmax(mx, dp[j.first.first][j.first.second]);
      chmax(mx2[j.first.first], dp[j.first.first][j.first.second]);
      chmax(mx2[j.first.second], dp[j.first.first][j.first.second]);
    }
  }
  int ans = 0;
  rep(i, n + 1) {
    rep(j, n + 1) {
      int ad = 0;
      if (i == j && j == a.back())
        ad++;
      chmax(ans, dp[i][j] + ad + tmp);
    }
  }
  cout << ans << "\\n";
}

Error: TLE

Fixed submission:

#include <algorithm>
#include <assert.h>
#include <bitset>
#include <cmath>
#include <complex>
#include <cstdlib>
#include <ctime>
#include <fstream>
#include <functional>
#include <iostream>
#include <map>
#include <queue>
#include <set>
#include <stack>
#include <string>
#include <unordered_map>
#include <vector>
using namespace std;
typedef long long ll;
typedef vector<ll> vl;
typedef vector<vl> vvl;
typedef vector<char> vc;
typedef vector<string> vs;
typedef vector<bool> vb;
typedef vector<double> vd;
typedef pair<ll, ll> P;
typedef pair<int, int> pii;
typedef vector<P> vpl;
typedef tuple<ll, ll, ll> tapu;
#define rep(i, n) for (int i = 0; i < (n); i++)
#define REP(i, a, b) for (int i = (a); i < (b); i++)
#define all(x) (x).begin(), (x).end()
#define rall(x) (x).rbegin(), (x).rend()
const int inf = 1 << 30;
const ll linf = 1LL << 62;
const int MAX = 510000;
ll dy[8] = {1, -1, 0, 0, 1, -1, 1, -1};
ll dx[8] = {0, 0, 1, -1, 1, -1, -1, 1};
const double pi = acos(-1);
const double eps = 1e-7;
template <typename T1, typename T2> inline bool chmin(T1 &a, T2 b) {
  if (a > b) {
    a = b;
    return true;
  } else
    return false;
}
template <typename T1, typename T2> inline bool chmax(T1 &a, T2 b) {
  if (a < b) {
    a = b;
    return true;
  } else
    return false;
}
template <typename T> inline void print(T &a) {
  rep(i, a.size()) cout << a[i] << " ";
  cout << "\\n";
}
template <typename T1, typename T2> inline void print2(T1 a, T2 b) {
  cout << a << " " << b << "\\n";
}
template <typename T1, typename T2, typename T3>
inline void print3(T1 a, T2 b, T3 c) {
  cout << a << " " << b << " " << c << "\\n";
}
ll pcount(ll x) { return __builtin_popcountll(x); }
const int mod = 1e9 + 7;
// const int mod = 998244353;

map<pii, ll> cur, nxt;

int main() {
  int n;
  cin >> n;
  int N = 3 * n;
  vl a(N);
  rep(i, N) cin >> a[i];
  rep(i, 5) {
    rep(j, i) {
      int m = -1;
      int ad = 1;
      rep(k, 5) {
        if (k == i || k == j)
          continue;
        if (m == -1)
          m = a[k];
        else {
          if (m != a[k]) {
            ad = 0;
            break;
          }
        }
      }
      int fi = a[i], se = a[j];
      if (fi > se)
        swap(fi, se);
      cur[{fi, se}] = ad;
    }
  }
  REP(i, 1, n - 1) {
    int id = i * 3;
    for (auto j : cur) {
      vector<int> v(5);
      v[0] = j.first.first;
      v[1] = j.first.second;
      v[2] = a[id + 2];
      v[3] = a[id + 3];
      v[4] = a[id + 4];
      rep(k, 5) {
        rep(l, k) {
          int p = -1;
          int ad = 1;
          rep(m, 5) {
            if (m == k || m == l)
              continue;
            if (p == -1)
              p = v[m];
            else if (p != v[m]) {
              ad = 0;
              break;
            }
          }
          int fi = v[k], se = v[l];
          if (fi > se)
            swap(fi, se);
          chmax(nxt[{fi, se}], j.second + ad);
        }
      }
    }
    cur = nxt;
  }
  int ans = 0;
  for (auto i : cur) {
    int ad = 0;
    if (i.first.first == i.first.second && i.first.second == a.back()) {
      ad = 1;
    }
    chmax(ans, i.second + ad);
  }
  cout << ans << "\\n";
}