【每日一题Day52】LC1691堆叠长方体的最大高度 | 贪心 + dp

简介: 实现:先将每个长方体的三边从小到大排序,然后将每个长方体根据最长边从大到小排序,然后使用动态规划查找以第i个长方体为顶层的最大高度,最后使用变量记录最大高度

堆叠长方体的最大高度【LC1691】


Given n cuboids where the dimensions of the ith cuboid is cuboids[i] = [widthi, lengthi, heighti] (0-indexed). Choose a subset of cuboids and place them on each other.


You can place cuboid i on cuboid j if widthi <= widthj and lengthi <= lengthj and heighti <= heightj. You can rearrange any cuboid’s dimensions by rotating it to put it on another cuboid.


Return the maximum height of the stacked cuboids.


啊啊啊 赶紧写完这个本子回家 我要回家!!!!


  • 思路:贪心


。局部最优:尽量取最高的边作为长方体的高

。全局最优:堆叠长方体的最大高度最高


  • 实现:先将每个长方体的三边从小到大排序,然后将每个长方体根据最长边从大到小排序,然后使用动态规划查找以第i个长方体为顶层的最大高度,最后使用变量记录最大高度


动态规划


1.确定dp数组(dp table)以及下标的含义


dp[i]:以第i个长方体为顶层的最大高度


2.确定递推公式


对于第i个箱子,需要枚举其可能的下一层的长方体j ,经过排序后,即为编号在其之前的长方体


dp[i]=min(dp[i],dp[j]+cuboids[i][2])


3.如何初始化


初始化为每个长方体的最长边


。dp[0]=cuboids[i][2];


4.确定遍历顺序


由dp公式可知,外层正序遍历行i,内层正序遍历列j


5.举例推导dp数组


  • 代码


class Solution {
    public int maxHeight(int[][] cuboids) {
        int n = cuboids.length;
        for(int i = 0; i < n; i++){
            Arrays.sort(cuboids[i]);
        }
        Arrays.sort(cuboids, new Comparator<int[]>(){
            public int compare(int[] c1,int []c2){
                if (c2[2] == c1[2]){
                    if (c2[1] == c1[1]){
                        return c2[0] - c1[0];
                    }else{
                        return c2[1] - c1[1];
                    }
                }
                return c2[2] - c1[2];
            }
        });
        // Arrays.sort(cuboids, (b, a) -> (a[0] + a[1] + a[2]) - (b[0] + b[1] + b[2]));
        int[] dp = new int[n];
        int ans = 0;
        for (int i = 0; i < n; i++){
            dp[i] = cuboids[i][2];
            for (int j = 0; j < i; j++){
                if (cuboids[i][0] <= cuboids[j][0] && cuboids[i][1] <= cuboids[j][1] && cuboids[i][2] <= cuboids[j][2]){
                    dp[i] = Math.max(dp[i], dp[j] + cuboids[i][2]);
                }
            }
            ans = Math.max(ans, dp[i]);            
        }
        return ans;
    }
}


。复杂度


  • 时间复杂度:O ( n 2 ) ,n 为长方体个数
  • 空间复杂度:O ( n 2 )
目录
相关文章
|
5天前
|
人工智能 BI
【每日一题Day267】LC834树中距离之和 | 换根dp
【每日一题Day267】LC834树中距离之和 | 换根dp
22 0
|
5天前
【每日一题Day302】LC849到最近的人的最大距离 | 贪心+分类讨论
【每日一题Day302】LC849到最近的人的最大距离 | 贪心+分类讨论
28 0
|
5天前
【每日一题Day342】LC2578最小和分割 | 贪心
【每日一题Day342】LC2578最小和分割 | 贪心
21 0
|
5天前
【每日一题Day114】LC1223 掷骰子模拟 | 记忆化搜索+dp
【每日一题Day114】LC1223 掷骰子模拟 | 记忆化搜索+dp
34 0
|
5天前
【每日一题Day144】LC1617统计子树中城市之间最大距离 | 树形dp
【每日一题Day144】LC1617统计子树中城市之间最大距离 | 树形dp
19 0
|
5天前
【每日一题Day309】LC823带因子的二叉树 | dp
【每日一题Day309】LC823带因子的二叉树 | dp
21 0
|
5天前
【每日一题Day262】LC1911最大子序列交替和 | dp
【每日一题Day262】LC1911最大子序列交替和 | dp
26 0
|
5天前
|
机器学习/深度学习
【每日一题Day271】LC918环形子数组的最大和 | 分类讨论 + dp
【每日一题Day271】LC918环形子数组的最大和 | 分类讨论 + dp
22 0
【每日一题Day271】LC918环形子数组的最大和 | 分类讨论 + dp
|
5天前
|
vr&ar
【每日一题Day166】LC1053交换一次的先前排列 | 贪心
【每日一题Day166】LC1053交换一次的先前排列 | 贪心
51 1
|
5天前
【每日一题Day224】LC2517礼盒的最大甜蜜度 | 二分答案
【每日一题Day224】LC2517礼盒的最大甜蜜度 | 二分答案
15 0