1. 程式人生 > >546. 移除盒子

546. 移除盒子

給出一些不同顏色的盒子,盒子的顏色由數字表示,即不同的數字表示不同的顏色。
你將經過若干輪操作去去掉盒子,直到所有的盒子都去掉為止。每一輪你可以移除具有相同顏色的連續 k 個盒子(k >= 1),這樣一輪之後你將得到 k*k 個積分。
當你將所有盒子都去掉之後,求你能獲得的最大積分和。

示例 1:
輸入:[1, 3, 2, 2, 2, 3, 4, 3, 1]

輸出:23

解釋:

[1, 3, 2, 2, 2, 3, 4, 3, 1] 
----> [1, 3, 3, 4, 3, 1] (3*3=9 分) 
----> [1, 3, 3, 3, 1] (1*1=1 分) 
----> [1, 1] (3*3=9 分) 
----> [] (2*2=4 分)

提示:盒子的總數 n 不會超過 100。

class Solution {
public:
    int removeBoxes(vector<int>& boxes) {
        int n = boxes.size();
        int dp[n][n][n] = {0};
        for (int i = 0; i < n; ++i) {
            for (int k = 0; k <= i; ++k) {
                dp[i][i][k] = (1 + k) * (1 + k);
            }   
        }
        for (int t = 1; t < n; ++t) {
            for (int j = t; j < n; ++j) {
                int i = j - t;
                for (int k = 0; k <= i; ++k) {
                    int res = (1 + k) * (1 + k) + dp[i + 1][j][0];
                    for (int m = i + 1; m <= j; ++m) {
                        if (boxes[m] == boxes[i]) {
                            res = max(res, dp[i + 1][m - 1][0] + dp[m][j][k + 1]);
                        }
                    }
                    dp[i][j][k] = res;
                }
            }
        }
        return n == 0 ? 0 : dp[0][n - 1][0];
    }
};