leetcode546。ボックス/動的プログラミングを削除する

件名: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;
        }
    }
};

おすすめ

転載: blog.csdn.net/qq_31672701/article/details/108023256