首页 > 其他分享 >Leetcode 1691. 堆叠长方体的最大高度

Leetcode 1691. 堆叠长方体的最大高度

时间:2024-02-10 13:33:36浏览次数:21  
标签:高度 堆叠 cuboids 1691 维度 长方体 Leetcode dp

https://leetcode.cn/problems/maximum-height-by-stacking-cuboids/description/

给你 n 个长方体 cuboids ,其中第 i 个长方体的长宽高表示为 cuboids[i] = [widthi, lengthi, heighti](下标从 0 开始)。
请你从 cuboids 选出一个 子集 ,并将它们堆叠起来。
如果 widthi <= widthj 且 lengthi <= lengthj 且 heighti <= heightj ,你就可以将长方体 i 堆叠在长方体 j 上。
你可以通过旋转把长方体的长宽高重新排列,以将它放在另一个长方体上。
返回 堆叠长方体 cuboids 可以得到的 最大高度 。
示例 1:

输入:cuboids = [[50,45,20],[95,37,53],[45,23,12]]
输出:190
解释:
第 1 个长方体放在底部,53x37 的一面朝下,高度为 95 。
第 0 个长方体放在中间,45x20 的一面朝下,高度为 50 。
第 2 个长方体放在上面,23x12 的一面朝下,高度为 45 。
总高度是 95 + 50 + 45 = 190 。

示例 2:
输入:cuboids = [[38,25,45],[76,35,3]]
输出:76
解释:
无法将任何长方体放在另一个上面。
选择第 1 个长方体然后旋转它,使 35x3 的一面朝下,其高度为 76 。


示例 3:
输入:cuboids = [[7,11,17],[7,17,11],[11,7,17],[11,17,7],[17,7,11],[17,11,7]]
输出:102
解释:
重新排列长方体后,可以看到所有长方体的尺寸都相同。
你可以把 11x7 的一面朝下,这样它们的高度就是 17 。
堆叠长方体的最大高度为 6 * 17 = 102 。
 
提示:
n == cuboids.length
1 <= n <= 100
1 <= widthi, lengthi, heighti <= 100

根据题目的数据范围
我们将每个长方体的可能的长宽高组合都考虑进去,那么每个长方体有6个组合(123,132,213,231,312,321),制作一个新的数据队列进行01背包动态规划,
保证不多次选择同一个长方体也是能够通过的。复杂度是O(n^2),只是n扩大了6倍。
我们这里考虑优化计算方式.
1 将每个长方体的三个维度进行从小到大排序
2 按照排序后的长方体按照三个维度关键字进行排序。
3 进行dp,寻找符合条件的最长上升子序列(排序中,长方体最大的那个维度作为高来使用)
这种做法需要证明两个问题:

1 为什么每个长方体的三个维度进行排序,再按照三个维度关键字进行排序,就保证正确答案在里面。

也就是长方体{1,2,3}能堆叠在长方体{4,5,6}, {2,3,1}能堆叠在{6,4,5}上 是相同。
{4,5,3}能堆叠在(5,3,7}上和 {3,4,5}能堆叠在{3,5,7}上是相同的。

设两个长方体,A={a1,a2,a3},B={b1,b2,b3} ,并且a1<=a2<=a3, b1<=b2<=b3

A能堆叠在B上,要求证明当且仅当a1<=b1 ,a2<=b2,a3<=b3

1 a1<=b1 ,a2<=b2,a3<=b3    推导出===>  A能堆叠在B上 这是题目的定义
2  A能堆叠在B上  推导出==>   a1<=b1,a2<=b2,a3<=b3

因为已有a1<=a2<=a3, b1<=b2<=b3,A能堆叠在B上,那么一定有 最小的a1<=b1,最大的 b3>=(a1,a2,a3) 也就是a3<=b3,否则A不可能堆叠在B上
同样的a2不可能>B3,如果a2>B2,那么A不可能堆叠在B上。所以a2<=b2.

2 为什么长方体排序后,使用最大的维度作为高度,就得到 堆叠长方体的最大高度。

这是因为我们在求最长递增子序列,在确定了子序列的最长长度,使用维度最高的边作为高度,那么他们的高度和就是最大高度。
假设有其他更高的不全部使用最长维度作为高度的选择组合,这个选择组合的长度需要比最长上升序列的长度至少要大一。
但是不存在比最长上升序列更长的上升序列。 所以把最长的边作为高是最优的。

两个问题解决后,代码如下

class Solution {
public:
    int maxHeight(vector<vector<int>>& cuboids) {
        //长方体的维度排序和长方体的三维度排序
        for (auto& e : cuboids) {
            sort(e.begin(), e.end());
        }
        sort(cuboids.begin(),cuboids.end());
         //插入一个元素,dp可以从1 开始 避免边界问题
        cuboids.insert(cuboids.begin(), vector<int>{0,0,0});
        int dp[105]; memset(dp,-0x3f,sizeof dp);
        dp[0] = 0;
        //dp[i] 等于以第i个长方体结尾的最大高度
        for (int i = 1; i < cuboids.size(); i++) {
            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] = max(dp[i], dp[j] + cuboids[i][2]);
                }
            }
        }
        //得到以任意长方体结尾的最大高度中的最大值
        int ans = 0;
        for (int i = 0; i < cuboids.size(); i++) {
            ans = max(ans, dp[i]);
        }

        return ans;
    }
};

我的视频题解空间

标签:高度,堆叠,cuboids,1691,维度,长方体,Leetcode,dp
From: https://www.cnblogs.com/itdef/p/18012838

相关文章

  • [LeetCode] 2641. Cousins in Binary Tree II
    Giventherootofabinarytree,replacethevalueofeachnodeinthetreewiththesumofallitscousins'values.Twonodesofabinarytreearecousinsiftheyhavethesamedepthwithdifferentparents.Returntherootofthemodifiedtree.Note......
  • Leetcode刷题第九天-回溯
    113:路径总和II链接:113.路径总和II-力扣(LeetCode)root=[-2,null,-3],targetSum=-5莫要忘记负数情况......
  • [LeetCode] LCP 30. 魔塔游戏
    小扣当前位于魔塔游戏第一层,共有N个房间,编号为0~N-1。每个房间的补血道具/怪物对于血量影响记于数组nums,其中正数表示道具补血数值,即血量增加对应数值;负数表示怪物造成伤害值,即血量减少对应数值;0表示房间对血量无影响。小扣初始血量为1,且无上限。假定小扣原计划按房间编......
  • leetcode--5. 最长回文子串(dp)
    记录23:292024-2-5https://leetcode.cn/problems/longest-palindromic-substring/dp[i][j]s[i,j]之间能否构成回文子串[i,j]之间是否能够构成需要考虑[i+1,j-1]是否构成回文子串且s[i]==s[j]当j-1>=i+1时候说明正好是俩个相邻的字符,此时如果s[i]==s[j]就肯定可......
  • leetcode 第141题:环形列表
    leetcode第141题:环形列表第一种:哈希列表publicbooleanhasCycle(ListNodehead){Set<ListNode>seen=newHashSet<ListNode>();while(head!=null){if(seen.contains(head)){returntrue;}......
  • leetcode 152 动态规划
    Problem:152.乘积最大子数组目录思路解题方法复杂度Code思路动态规划的题型见到了就记录一下吧,接触到的并不多,也不太会。这道题主要是有负数,所以需要维护两个变量,我们希望最大值尽可能大,也希望负数最小值尽可能小,因为如果下一位是负数,相乘可以变成正数,最小值就会变成最大值......
  • leetcode 第176题:第二高的薪水
    leetcode数据库第176题:第二高的薪水第一种:去掉最大的薪水,选取第二大的薪水selectmax(salary)asSecondHighestSalaryfromEmployeewheresalary<(selectmax(salary)fromEmployee);第二种:嵌套查询+去除null+去重要想获取第二高,需要排序,使用orderby(默认是升序a......
  • Leetcode刷题第八天-回溯
    22:括号生成链接:22.括号生成-力扣(LeetCode)括号是一对,所以每一次递归结束条件是字符串长度=2*n有效括号判断:'('个数==')'个数时,当前必须是'(','('个数==n时,必须是')',其他情况当前位置遍历两边,既可以是'('又可以是')'1classSolution:2defgenerateParenth......
  • [LeetCode] 2966. Divide Array Into Arrays With Max Difference
    Youaregivenanintegerarraynumsofsizenandapositiveintegerk.Dividethearrayintooneormorearraysofsize3satisfyingthefollowingconditions:Eachelementofnumsshouldbeinexactlyonearray.Thedifferencebetweenanytwoelementsin......
  • leetcode85. 最大矩形
    85.最大矩形-力扣(LeetCode)参考dp求最大字串和的思想,将一维dp转化为二维的形式,将当前列的和当成一维的数进行dp即可。这题和求最大子矩阵和的dp思路一样。1classSolution{2public:3intmaximalRectangle(vector<vector<char>>&matrix){4intn=m......