Problem p02581 (C++) — buggy submission, verdict: Runtime Error

/*
{By GWj
*/
#pragma GCC optimize(2)
#include <bits/stdc++.h>
#define rb(a, b, c) for (int a = b; a <= c; ++a)
#define rl(a, b, c) for (int a = b; a >= c; --a)
#define LL long long
#define IT iterator
#define PB push_back
#define II(a, b) make_pair(a, b)
#define FIR first
#define SEC second
#define FREO freopen("check.out", "w", stdout)
#define rep(a, b) for (int a = 0; a < b; ++a)
#define SRAND                                                                  \\
  mt19937 rng(chrono::steady_clock::now().time_since_epoch().count())
#define random(a) rng() % a
#define ALL(a) a.begin(), a.end()
#define POB pop_back
#define ff fflush(stdout)
#define fastio ios::sync_with_stdio(false)
#define R(a) cin >> a
#define R2(a, b) cin >> a >> b
#define check_min(a, b) a = min((a), (b))
#define check_max(a, b) a = max((a), (b))
using namespace std;
const int INF = 0x3f3f3f3f;
typedef pair<int, int> mp;
/*}
 */
const int MAXN = 2002;
int dp[MAXN][MAXN], save[MAXN], save2[MAXN][MAXN], delta /*全局增量*/, best,
    best2[MAXN]; // 滚动掉第一维
int best_, best2_[MAXN];
int n, a[MAXN * 3];
vector<vector<int>> cards;
int main() {
  //	freopen("ran.in","r",stdin);
  // 	freopen("Code.out","w",stdout);
  fastio;
  R(n);
  n = n + n + n;
  rb(i, 1, n) R(a[i]);
  if (n == 3) {
    int rest = 1;
    rb(i, 1, n) {
      if (a[i] == a[1])
        ;
      else
        rest = 0;
    }
    cout << rest << endl;
    return 0;
  }
  rb(j, 1, n / 3) {
    vector<int> tmp;
    if (j == 1) {
      rb(i, 1, 5) { tmp.PB(a[i]); }
      cards.PB(tmp);
    } else {
      if (j == n / 3) {
        tmp.PB(a[n]);
        cards.PB(tmp);
      } else {
        rb(i, (j - 2) * 3 + 5 + 1, (j - 1) * 3 + 5) { tmp.PB(a[i]); }
        cards.PB(tmp);
      }
    }
  }
  memset(dp, -63, sizeof(dp));
  rep(i, 5) rep(j, 5) {
    if (i != j) {
      bool ok = 1;
      int las = -1;
      rep(k, 5) {
        if (k == i || k == j)
          continue;
        if (las != -1 && las != cards[0][k]) {
          ok = 0;
        }
        las = cards[0][k];
      }
      dp[cards[0][i]][cards[0][j]] = dp[cards[0][j]][cards[0][i]] = ok;
    }
  }
  best = -INF;
  memset(best2, -63, sizeof(best2));
  n /= 3;
  rb(i, 1, n) {
    rb(j, 1, n) { check_max(best2[i], dp[i][j]); }
    check_max(best, best2[i]);
  }
  //	rb(i,1,n){
  //		rb(j,1,n){
  //			cout<<dp[i][j];
  //			if(j!=n) cout<<" ";
  //		}
  //		cout<<endl;
  //	}
  //	cout<<endl;
  rb(i, 1, n - 2) {
    rb(j, 1, n) save[j] = dp[j][j];
    rep(j, 3) rb(k, 1, n) save2[cards[i][j]][k] = dp[cards[i][j]][k];
    best_ = best;
    rb(j, 1, n) best2_[j] = best2[j];
    bool ok = 1;
    rep(j, 3) {
      if (cards[i][j] == cards[i][0])
        ;
      else {
        ok = 0;
      }
    }
    if (ok) {
      delta++;
      continue;
    }
    /*枚举只有拿了1张牌的情况*/
    rep(j_, 3) { // 拿走哪一张
      // 枚举另一张
      int j = cards[i][j_];
      int need = -1;
      rep(k_, 3) {
        int k = cards[i][k_];
        if (k_ != j_) {
          if (need == -1) {
            need = k;
          } else {
            if (need != k)
              need = -1;
          }
        }
      }
      rb(k, 1, n) {
        check_max(dp[j][k], best2[k]);
        check_max(dp[k][j], best2[k]);
        //				if(k==4){
        //					cout<<j<<"-"<<dp[j][k]<<"
        //"<<best2[k]<<endl;
        //				}
        if (need > 0)
          check_max(dp[k][j], save2[need][k] + 1);
        check_max(dp[j][k], dp[k][j]);
        check_max(best2_[k], dp[j][k]);
        check_max(best2_[j], dp[j][k]);
        check_max(best_, dp[j][k]);
      }
    }
    //		cout<<"ONE\\n";
    //			rb(i,1,n){
    //		rb(j,1,n){
    //			cout<<dp[i][j];
    //			if(j!=n) cout<<" ";
    //		}
    //		cout<<endl;
    //	}
    //	cout<<endl;
    /*枚举拿走两张的情况*/
    rep(j_, 3) rep(k_, 3) {
      if (j_ == k_)
        continue;
      int need = 0;
      rep(l_, 3) if (l_ != j_ && l_ != k_) { need = cards[i][l_]; }
      int j = cards[i][j_], k = cards[i][k_];
      check_max(dp[j][k], best);
      check_max(dp[j][k], save[need] + 1);
      check_max(dp[k][j], dp[j][k]);
      check_max(best2_[k], dp[j][k]);
      check_max(best2_[j], dp[j][k]);
      check_max(best_, dp[j][k]);
    }
    best = best_;
    rb(j, 1, n) best2[j] = best2_[j], assert(best >= best2[j]);
    //		cout<<i<<" "<<dp[4][4]<<endl;
    //	rb(i,1,n){
    //		rb(j,1,n){
    //			cout<<dp[i][j];
    //			if(j!=n) cout<<" ";
    //		}
    //		cout<<endl;
    //	}
    //	cout<<endl;
  }
  rb(i, 1, n) rb(j, 1, n) { assert(dp[i][j] == dp[j][i]); }
  //	cout<<dp[cards[n-1][0]][cards[n-1][0]]<<" "<<delta<<endl;
  //	cout<<best<<" "<<dp[cards[n-1][0]][cards[n-1][0]]+1<<endl;
  check_max(best, dp[cards[n - 1][0]][cards[n - 1][0]] + 1);
  cout << best + delta << endl;
  return 0;
} /*
 5
 1 2 5 3 3 5 3 1 3 4 3 2 5 1 4
 */

Error: 0

Fixed submission:

/*
{By GWj
*/
#pragma GCC optimize(2)
#include <bits/stdc++.h>
#define rb(a, b, c) for (int a = b; a <= c; ++a)
#define rl(a, b, c) for (int a = b; a >= c; --a)
#define LL long long
#define IT iterator
#define PB push_back
#define II(a, b) make_pair(a, b)
#define FIR first
#define SEC second
#define FREO freopen("check.out", "w", stdout)
#define rep(a, b) for (int a = 0; a < b; ++a)
#define SRAND                                                                  \\
  mt19937 rng(chrono::steady_clock::now().time_since_epoch().count())
#define random(a) rng() % a
#define ALL(a) a.begin(), a.end()
#define POB pop_back
#define ff fflush(stdout)
#define fastio ios::sync_with_stdio(false)
#define R(a) cin >> a
#define R2(a, b) cin >> a >> b
#define check_min(a, b) a = min(a, b)
#define check_max(a, b) a = max(a, b)
using namespace std;
const int INF = 0x3f3f3f3f;
typedef pair<int, int> mp;
/*}
 */
const int MAXN = 2002;
int dp[MAXN][MAXN], save[MAXN], save2[MAXN][MAXN], delta /*全局增量*/, best,
    best2[MAXN]; // 滚动掉第一维
int best_, best2_[MAXN];
int n, a[MAXN * 3];
vector<vector<int>> cards;
int main() {
  fastio;
  R(n);
  n = n + n + n;
  rb(i, 1, n) R(a[i]);
  if (n == 1) {
    int rest = 1;
    rb(i, 1, n) {
      if (a[i] == a[1])
        ;
      else
        rest = 0;
    }
    cout << rest << endl;
    return 0;
  }
  rb(j, 1, n / 3) {
    vector<int> tmp;
    if (j == 1) {
      rb(i, 1, 5) { tmp.PB(a[i]); }
      cards.PB(tmp);
    } else {
      if (j == n / 3) {
        tmp.PB(a[n]);
        cards.PB(tmp);
      } else {
        rb(i, (j - 2) * 3 + 5 + 1, (j - 1) * 3 + 5) { tmp.PB(a[i]); }
        cards.PB(tmp);
      }
    }
  }
  memset(dp, -63, sizeof(dp));
  rep(i, 5) rep(j, 5) {
    if (i != j) {
      bool ok = 1;
      int las = -1;
      rep(k, 5) {
        if (k == i || k == j)
          continue;
        if (las != -1 && las != cards[0][k]) {
          ok = 0;
        }
        las = cards[0][k];
      }
      dp[cards[0][i]][cards[0][j]] = dp[cards[0][j]][cards[0][i]] = ok;
    }
  }
  rb(i, 1, n) {
    rb(j, 1, n) { check_max(best2[i], dp[i][j]); }
    check_max(best, best2[i]);
  }
  n /= 3;
  rb(i, 1, n - 2) {
    rb(j, 1, n) save[j] = dp[j][j];
    rep(j, 3) rb(k, 1, n) save2[cards[i][j]][k] = dp[cards[i][j]][k];
    best_ = best;
    rb(j, 1, n) best2_[j] = best2[j];
    bool ok = 1;
    rep(j, 3) {
      if (cards[i][j] == cards[i][0])
        ;
      else {
        ok = 0;
      }
    }
    if (ok) {
      delta++;
      continue;
    }
    /*枚举只有拿了以张牌的情况*/
    rep(j_, 3) { // 拿走哪一张
      // 枚举另一张
      int j = cards[i][j_];
      int need = -1;
      rep(k_, 3) {
        int k = cards[i][k_];
        if (k_ != j_) {
          if (need == -1) {
            need = k;
          } else {
            if (need != k)
              need = -1;
          }
        }
      }
      rb(k, 1, n) {
        check_max(dp[j][k], best2[k]);
        check_max(dp[k][j], best2[k]);
        if (need > 0)
          check_max(dp[k][j], save2[need][k] + 1);
        check_max(dp[j][k], dp[k][j]);
        check_max(best2_[k], dp[j][k]);
        check_max(best2_[j], dp[j][k]);
        check_max(best_, dp[j][k]);
      }
    }
    /*枚举拿走两张的情况*/
    rep(j_, 3) rep(k_, 3) {
      if (j_ == k_)
        continue;
      int need = 0;
      rep(l_, 3) if (l_ != j_ && l_ != k_) { need = cards[i][l_]; }
      int j = cards[i][j_], k = cards[i][k_];
      check_max(dp[j][k], best);
      check_max(dp[j][k], save[need] + 1);
      check_max(dp[k][j], dp[j][k]);
      check_max(best2_[k], dp[j][k]);
      check_max(best2_[j], dp[j][k]);
      check_max(best_, dp[j][k]);
    }
    best = best_;
    rb(j, 1, n) best2[j] = best2_[j];
  }
  check_max(best, dp[cards[n - 1][0]][cards[n - 1][0]] + 1);
  cout << best + delta << endl;
  return 0;
}