class Solution {
public:
int removeBoxes(vector<int> &boxes);
};
int Solution::removeBoxes(vector<int> &a) {
int n = a.size();
vector<vector<vector<int>>> dp(
n + 1, vector<vector<int>>(n + 1, vector<int>(n + 2, 0)));
// dp[i][j][f] is the maximum points for the subarray [i...j]
// when f boxes with color a[i] are added at the start.
for (int i = n - 1; i >= 0; i--) {
for (int j = i; j < n; j++) {
for (int f = 0; f <= n; f++) {
int nf = f + 1;
// Collapse whatever has been accumulated so far.
dp[i][j][f] = nf * nf + dp[i + 1][j][0];
// Merge it with an identical colored box.
for (int k = i + 1; k <= j; k++) {
if (a[i] != a[k]) {
continue;
}
dp[i][j][f] =
max(dp[i][j][f], dp[i + 1][k - 1][0] + dp[k][j][nf]);
}
}
}
}
return dp[0][n - 1][0];
}