件名:546。箱を外します
いくつかの異なる色のボックスを考えると、ボックスの色は数字で表されます。つまり、異なる数字は異なる色を表します。
すべてのボックスが削除されるまで、ボックスを削除するために数ラウンドの操作を実行します。各ラウンドでは、同じ色(k> = 1)のk個の連続するボックスを削除できるため、1回のラウンドの後にk * kポイントを獲得できます。
すべてのボックスを削除した後、取得できるポイントの最大合計を見つけます。
例:
输入:boxes = [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 分)
促す:
- 1 <= boxs.length <= 100
- 1 <=ボックス[i] <= 100
出典:LeetCode(LeetCode)
リンク:https ://leetcode-cn.com/problems/remove-boxes
著作権はLeetCode が所有しています。商用転載については、正式な許可書にご連絡ください。非商用転載については、出典を明記してください。
基本的な考え方1:動的プログラミング
- dp [l] [r] [k]:区間[l、r]に区間の右端と右端に等しいk要素(boxs [r])を加えたものを削除したときの最大結果を表します
- 要素のすべての組み合わせを適切なエンドポイントでトラバースし、最大値を取ります
- 最終結果はdp [0] [boxes.size()-1] [0]に格納されます
もう少し言うと、
この動的プログラミングの考え方は、以下のdfsの考え方とは異なります。DFSは、すべての状況をトラバースすることによって得られる最終結果の最大値であり、動的プログラミングは、現在の間隔に接続できる要素と、一緒に削除する適切なエンドポイントを見つけることです。
class Solution {
public:
int dp[100][100][100];
int removeBoxes(vector<int>& boxes) {
memset(dp, 0, sizeof dp);
return fun(boxes, 0, boxes.size() - 1, 0);
}
int fun(vector<int>& boxes, int l, int r, int k){
if(l > r)
return 0;
if(dp[l][r][k])
return dp[l][r][k];
while(l < r && boxes[r] == boxes[r - 1]){
//当右端点左面的元素和右端点相等时,尽可能的将右端点左移,使得相同元素的长度最长
--r;
++k;
}
dp[l][r][k] = fun(boxes, l, r - 1, 0) + (k + 1) * (k + 1);
//右端点左面和右端点相等组成连续序列的情况
for(int i = l; i < r; ++i){
if(boxes[i] == boxes[r]){
dp[l][r][k] = max(dp[l][r][k], fun(boxes, l, i, k + 1) + fun(boxes, i + 1, r - 1, 0));
}
}
return dp[l][r][k];
}
};
基本的な考え方2:dfs(タイムアウト)
すべての可能性をトラバースし、結果はタイムアウトしました
class Solution {
public:
struct Node{
int val, cnt;
Node(int a, int b): val(a), cnt(b){
}
};
int removeBoxes(vector<int>& boxes) {
if(boxes.size() == 0)
return 0;
vector<Node> nums;
nums.push_back(Node(boxes[0], 1));
for(int i = 1; i < boxes.size(); ++i){
if(boxes[i] == nums.back().val)
nums.back().cnt++;
else
nums.push_back(Node(boxes[i], 1));
}
int res = 0;
dfs(nums, res, 0);
return res;
}
void dfs(vector<Node> &nums, int &res, int cur){
//cout << cur << endl;
if(nums.size() == 0){
res = max(res, cur);
return;
}
for(int i = 0; i < nums.size(); ++i){
auto nums_copy = nums;
int c = nums[i].cnt;
if(i > 0 && i + 1 < nums.size() && nums[i - 1].val == nums[i + 1].val){
nums[i - 1].cnt += nums[i + 1].cnt;
nums.erase(nums.begin() + i, nums.begin() + i + 2);
}
else
nums.erase(nums.begin() + i);
dfs(nums, res, cur + c * c);
nums = nums_copy;
}
}
};