leetcode546. Quitar caja / programación dinámica

Asunto: 546. Quite la caja

Dadas algunas cajas de diferentes colores, los colores de las cajas están representados por números, es decir, diferentes números representan diferentes colores.
Pasará por varias rondas de operaciones para eliminar las cajas hasta que se eliminen todas. En cada ronda puedes eliminar k casillas consecutivas del mismo color (k> = 1), por lo que obtendrás k * k puntos después de una ronda.
Después de eliminar todas las casillas, encuentre la suma máxima de puntos que puede obtener.

Ejemplo:

输入: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)

rápido:

  • 1 <= cajas.longitud <= 100
  • 1 <= casillas [i] <= 100

Fuente: LeetCode
Enlace: https://leetcode-cn.com/problems/remove-boxes Los
derechos de autor son propiedad de LeetCode . Para reimpresiones comerciales, comuníquese con la autorización oficial. Para reimpresiones no comerciales, indique la fuente.

Idea básica 1: programación dinámica

  • dp [l] [r] [k]: Representa el resultado máximo obtenido al eliminar el intervalo [l, r] más k elementos que son iguales a los extremos derecho y derecho del intervalo (es decir, cuadros [r])
  • Atraviese cada combinación de elementos con el punto final correcto y tome el valor máximo
  • El resultado final se almacena en dp [0] [boxes.size () - 1] [0]

Para decir un poco más:
la idea de esta programación dinámica es diferente de la idea de dfs a continuación. DFS es el valor máximo del resultado final obtenido al atravesar todas las situaciones, mientras que la programación dinámica es encontrar los elementos que se pueden conectar con el intervalo actual y el punto final correcto para eliminar juntos. .

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];
    }
};

Idea básica 2: dfs (tiempo de espera agotado)

Atraviesa todas las posibilidades, el resultado se agotó

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;
        }
    }
};

Supongo que te gusta

Origin blog.csdn.net/qq_31672701/article/details/108023256
Recomendado
Clasificación