main.cc 1.2 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253
  1. #include <algorithm>
  2. #include <cstdio>
  3. #include <cstring>
  4. using namespace std;
  5. const int N = 200;
  6. int dp[N][N][N];
  7. // dp[i][j][k] means the highest score for clearing blocks i ~ j.
  8. struct Segment {
  9. int color;
  10. int len;
  11. };
  12. Segment seg[N];
  13. // Clear the blocks from i to j, with extra len of block having the same color as seg[j].
  14. int clear(int i, int j, int len) {
  15. if (dp[i][j][len] != -1) return dp[i][j][len];
  16. int score = (seg[j].len + len) * (seg[j].len + len);
  17. if (i == j) return score;
  18. score += clear(i, j - 1, 0);
  19. for (int k = i; k + 1 <= j - 1; k++) {
  20. if (seg[k].color != seg[j].color) continue;
  21. score = max(score, clear(k + 1, j - 1, 0) + clear(i, k, seg[j].len + len));
  22. }
  23. dp[i][j][len] = score;
  24. return score;
  25. }
  26. int main() {
  27. int T, n;
  28. scanf("%d", &T);
  29. for (int t = 1; t <= T; t++) {
  30. scanf("%d", &n);
  31. int cnt = -1, pre = -1;
  32. for (int i = 0; i < n; i++) {
  33. int color;
  34. scanf("%d", &color);
  35. if (color != pre) {
  36. seg[++cnt].color = color;
  37. seg[cnt].len = 1;
  38. pre = color;
  39. } else {
  40. seg[cnt].len++;
  41. }
  42. }
  43. memset(dp, 0xFF, sizeof(dp));
  44. printf("Case %d: %d\n", t, clear(0, cnt, 0));
  45. }
  46. return 0;
  47. }