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


#include <iostream>

using namespace std;

const int kMaxN = 2002;

int a[kMaxN * 3];
int f[kMaxN * 3][kMaxN * 3], p[kMaxN][kMaxN];
int n, ans;

void T0(int i, int j, int g) { // 用g组的卡替换i
  g *= 3;
  f[j][g] = max(f[j][g], f[i][j] + (a[i] == a[g + 1] && a[i] == a[g + 2]));
  f[j][g + 1] = max(f[j][g + 1], f[i][j] + (a[i] == a[g] && a[i] == a[g + 2]));
  f[j][g + 2] = max(f[j][g + 2], f[i][j] + (a[i] == a[g] && a[i] == a[g + 1]));
}

void T1(int i, int j, int g) { // 用g组的牌替换j
  g *= 3;
  f[i][g] = max(f[i][g], f[i][j] + (a[j] == a[g + 1] && a[j] == a[g + 2]));
  f[i][g + 1] = max(f[i][g + 1], f[i][j] + (a[j] == a[g] && a[j] == a[g + 2]));
  f[i][g + 2] = max(f[i][g + 2], f[i][j] + (a[j] == a[g] && a[j] == a[g + 1]));
}

void T2(int i, int j, int g) { // 用g组的牌替换i和j
  g *= 3;
  f[g][g + 1] = max(f[g][g + 1], f[i][j] + (a[i] == a[j] && a[i] == a[g + 2]));
  f[g][g + 2] = max(f[g][g + 2], f[i][j] + (a[i] == a[j] && a[i] == a[g + 1]));
  f[g + 1][g + 2] =
      max(f[g + 1][g + 2], f[i][j] + (a[i] == a[j] && a[i] == a[g]));
}

void P() { // 预处理
  int m = 2;
  for (int i = 3; i < 3 * n; i += 3) {          // 枚举组
    if (a[i] == a[i + 1] && a[i] == a[i + 2]) { // 有一组相同直接消除
      ans++;
    } else {
      a[++m] = a[i], a[++m] = a[i + 1], a[++m] = a[i + 2];
    }
  }
  a[++m] = a[3 * n]; // 最后一组
  n = m / 3;
  for (int i = n; i >= 1; i--) { // 预处理每组之后每种数字第一次出现的组
    for (int j = 1; j <= n; j++) {
      p[i][j] = p[i + 1][j];
    }
    p[i][a[i * 3]] = p[i][a[i * 3 + 1]] = p[i][a[i * 3 + 2]] = i;
  }
}

int main() {
  cin >> n;
  for (int i = 1; i <= 3 * n; i++) {
    cin >> a[i];
  }
  P();
  for (int j = 1; j < 3 * n; j++) {
    for (int i = 1; i < j; i++) {
      int g = j / 3 + 1;
      T0(i, j, g);
      T1(i, j, g);
      T2(i, j, g);
      if (p[g + 1][a[i]]) {
        T0(i, j, p[g][a[i]]);
        T2(i, j, p[g][a[i]]);
      }
      if (p[g + 1][a[j]]) {
        T1(i, j, p[g][a[j]]);
        T2(i, j, p[g][a[j]]);
      }
    }
  }
  cout << ans + f[3 * n + 1][3 * n + 2];
  return 0;
}

Error: TLE

Fixed submission:

#include <algorithm>
#include <iostream>

using namespace std;

const int kMaxN = 2002;

struct E {
  int p, q;
} q[2][kMaxN * kMaxN];
int a[kMaxN * 3 + 2], b[6] = {-1};
int f[2][kMaxN][kMaxN], t[2][kMaxN][kMaxN], c[2];
int n;

bool C(int p, int q) {
  int y;
  for (y = 1; y == p || y == q; y++) {
  }
  for (int i = 1; i <= 5; i++) {
    if (i != p && i != q && b[i] != b[y]) {
      return 0;
    }
  }
  return 1;
}

int main() {
  // freopen("input.txt", "r", stdin);
  cin >> n;
  for (int i = 1; i <= 3 * n; i++) {
    cin >> a[i];
  }
  c[1] = 1;
  q[1][1] = {a[1], a[2]};
  for (int i = 1; i <= n; i++) {
    int x = i & 1;
    c[!x] = 0;
    for (int j = 1; j <= c[x]; j++) {
      b[1] = q[x][j].p, b[2] = q[x][j].q, b[3] = a[i * 3], b[4] = a[i * 3 + 1],
      b[5] = a[i * 3 + 2];
      sort(b + 1, b + 6);
      for (int k = 1; k <= 5; k++) {
        if (b[k] != b[k - 1]) {
          for (int l = k + 1; l <= 5; l++) {
            if (l == k + 1 || b[l] != b[l - 1]) {
              if (t[!x][b[k]][b[l]] != i) {
                t[!x][b[k]][b[l]] = i;
                f[!x][b[k]][b[l]] = 0;
                q[!x][++c[!x]] = {b[k], b[l]};
              }
              f[!x][b[k]][b[l]] =
                  max(f[!x][b[k]][b[l]], f[x][q[x][j].p][q[x][j].q] + C(k, l));
            }
          }
        }
      }
    }
  }
  cout << f[!(n & 1)][0][0];
  return 0;
}