{"id":7814,"date":"2020-12-13T23:31:58","date_gmt":"2020-12-14T07:31:58","guid":{"rendered":"https:\/\/zxi.mytechroad.com\/blog\/?p=7814"},"modified":"2020-12-13T23:32:48","modified_gmt":"2020-12-14T07:32:48","slug":"leetcode-1691-maximum-height-by-stacking-cuboids","status":"publish","type":"post","link":"https:\/\/zxi.mytechroad.com\/blog\/dynamic-programming\/leetcode-1691-maximum-height-by-stacking-cuboids\/","title":{"rendered":"\u82b1\u82b1\u9171 LeetCode 1691. Maximum Height by Stacking Cuboids"},"content":{"rendered":"\n<p>Given&nbsp;<code>n<\/code>&nbsp;<code>cuboids<\/code>&nbsp;where the dimensions of the&nbsp;<code>i<sup>th<\/sup><\/code>&nbsp;cuboid is&nbsp;<code>cuboids[i] = [width<sub>i<\/sub>, length<sub>i<\/sub>, height<sub>i<\/sub>]<\/code>&nbsp;(<strong>0-indexed<\/strong>). Choose a&nbsp;<strong>subset<\/strong>&nbsp;of&nbsp;<code>cuboids<\/code>&nbsp;and place them on each other.<\/p>\n\n\n\n<p>You can place cuboid&nbsp;<code>i<\/code>&nbsp;on cuboid&nbsp;<code>j<\/code>&nbsp;if&nbsp;<code>width<sub>i<\/sub>&nbsp;&lt;= width<sub>j<\/sub><\/code>&nbsp;and&nbsp;<code>length<sub>i<\/sub>&nbsp;&lt;= length<sub>j<\/sub><\/code>&nbsp;and&nbsp;<code>height<sub>i<\/sub>&nbsp;&lt;= height<sub>j<\/sub><\/code>. You can rearrange any cuboid&#8217;s dimensions by rotating it to put it on another cuboid.<\/p>\n\n\n\n<p>Return&nbsp;<em>the&nbsp;<strong>maximum height<\/strong>&nbsp;of the stacked<\/em>&nbsp;<code>cuboids<\/code>.<\/p>\n\n\n\n<p><strong>Example 1:<\/strong><\/p>\n\n\n\n<figure class=\"wp-block-image\"><img decoding=\"async\" src=\"https:\/\/assets.leetcode.com\/uploads\/2019\/10\/21\/image.jpg\" alt=\"\"\/><\/figure>\n\n\n\n<pre class=\"wp-block-preformatted;crayon:false\"><strong>Input:<\/strong> cuboids = [[50,45,20],[95,37,53],[45,23,12]]\n<strong>Output:<\/strong> 190\n<strong>Explanation:<\/strong>\nCuboid 1 is placed on the bottom with the 53x37 side facing down with height 95.\nCuboid 0 is placed next with the 45x20 side facing down with height 50.\nCuboid 2 is placed next with the 23x12 side facing down with height 45.\nThe total height is 95 + 50 + 45 = 190.\n<\/pre>\n\n\n\n<p><strong>Example 2:<\/strong><\/p>\n\n\n\n<pre class=\"wp-block-preformatted;crayon:false\"><strong>Input:<\/strong> cuboids = [[38,25,45],[76,35,3]]\n<strong>Output:<\/strong> 76\n<strong>Explanation:<\/strong>\nYou can't place any of the cuboids on the other.\nWe choose cuboid 1 and rotate it so that the 35x3 side is facing down and its height is 76.\n<\/pre>\n\n\n\n<p><strong>Example 3:<\/strong><\/p>\n\n\n\n<pre class=\"wp-block-preformatted;crayon:false\"><strong>Input:<\/strong> cuboids = [[7,11,17],[7,17,11],[11,7,17],[11,17,7],[17,7,11],[17,11,7]]\n<strong>Output:<\/strong> 102\n<strong>Explanation:<\/strong>\nAfter rearranging the cuboids, you can see that all cuboids have the same dimension.\nYou can place the 11x7 side down on all cuboids so their heights are 17.\nThe maximum height of stacked cuboids is 6 * 17 = 102.\n<\/pre>\n\n\n\n<p><strong>Constraints:<\/strong><\/p>\n\n\n\n<ul class=\"wp-block-list\"><li><code>n == cuboids.length<\/code><\/li><li><code>1 &lt;= n &lt;= 100<\/code><\/li><li><code>1 &lt;= width<sub>i<\/sub>, length<sub>i<\/sub>, height<sub>i<\/sub>&nbsp;&lt;= 100<\/code><\/li><\/ul>\n\n\n\n<h2 class=\"wp-block-heading\"><strong>Solution: Math\/Greedy + DP<\/strong><\/h2>\n\n\n\n<p>Direct DP is very hard, since there is no orders.<\/p>\n\n\n\n<p>We have to find some way to sort the cuboids such that cuboid i can NOT stack on cuboid j if i &gt; j. Then dp[i] = max(dp[j]) + height[i], 0 &lt;= j &lt; i, for each i, find the best base j and stack on top of it.<br>ans = max(dp)<\/p>\n\n\n\n<p>We can sort the cuboids by their sorted dimensions, and cuboid i can stack stack onto cuboid j if and only if w[i] &lt;= w[j] and l[i] &lt;= l[j] and h[i] &lt;= h[j].<\/p>\n\n\n\n<p>First of all, we need to prove that all heights must come from the largest dimension of each cuboid. <br><br>1. If the top of the stack is A1*A2*A3, A3 &lt; max(A1, A2), we can easily swap A3 with max(A1, A2), it&#8217;s still stackable but we get larger heights.<br>e.g. 3x5x4, base is 3&#215;5, height is 4, we can rotate to get base of 3&#215;4 with height of 5.<\/p>\n\n\n\n<p>2. If a middle cuboid A of size A1*A2*A3, assuming A1 &gt;= A2, A1 &gt; A3, on top of A we have another cuboid B of size B1*B2*B3, B1 &lt;= B2 &lt;= B3.<br>We have A1 &gt;= B1, A2 &gt;= B2, A3 &gt;= B3, by rotating A we have A3*A2*A1<br>A3 &gt;= B3 &gt;= B1, A2 &gt;= B2, A1 &gt; A3 &gt;= B3, so B can be still on top of A, and we get larger height.<\/p>\n\n\n\n<p>e.g. A: 3x5x4, B: 2x3x4<br>A -&gt; 3x4x5, B is still stackable.<\/p>\n\n\n\n<p>&#8230;<\/p>\n\n\n\n<p>Time complexity: O(n^2)<br>Space complexity: O(n^2)<\/p>\n\n\n\n<div class=\"responsive-tabs\">\n<h2 class=\"tabtitle\">C++<\/h2>\n<div class=\"tabcontent\">\n\n<pre lang=\"c++\">\n\/\/ Author: Huahua\nclass Solution {\npublic:\n  int maxHeight(vector<vector<int>>& A) {\n    A.push_back({0, 0, 0});\n    const int n = A.size();\n    for (auto& box : A) sort(begin(box), end(box));\n    sort(begin(A), end(A));\n    vector<int> dp(n);\n    for (int i = 0; i < n; ++i)\n      for (int j = 0; j < i; ++j)\n        if (A[i][0] >= A[j][0] && A[i][1] >= A[j][1] && A[i][2] >= A[j][2])\n          dp[i] = max(dp[i], dp[j] + A[i][2]);\n    return *max_element(begin(dp), end(dp));\n  }\n};\n<\/pre>\n<\/div><\/div>\n","protected":false},"excerpt":{"rendered":"<p>Given&nbsp;n&nbsp;cuboids&nbsp;where the dimensions of the&nbsp;ith&nbsp;cuboid is&nbsp;cuboids[i] = [widthi, lengthi, heighti]&nbsp;(0-indexed). Choose a&nbsp;subset&nbsp;of&nbsp;cuboids&nbsp;and place them on each other. You can place cuboid&nbsp;i&nbsp;on cuboid&nbsp;j&nbsp;if&nbsp;widthi&nbsp;&lt;= widthj&nbsp;and&nbsp;lengthi&nbsp;&lt;= lengthj&nbsp;and&nbsp;heighti&nbsp;&lt;= heightj.&#8230;<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[46],"tags":[18,88,217,31,15],"class_list":["post-7814","post","type-post","status-publish","format-standard","hentry","category-dynamic-programming","tag-dp","tag-greedy","tag-hard","tag-math","tag-sorting","entry","simple"],"_links":{"self":[{"href":"https:\/\/zxi.mytechroad.com\/blog\/wp-json\/wp\/v2\/posts\/7814","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/zxi.mytechroad.com\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/zxi.mytechroad.com\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/zxi.mytechroad.com\/blog\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/zxi.mytechroad.com\/blog\/wp-json\/wp\/v2\/comments?post=7814"}],"version-history":[{"count":2,"href":"https:\/\/zxi.mytechroad.com\/blog\/wp-json\/wp\/v2\/posts\/7814\/revisions"}],"predecessor-version":[{"id":7816,"href":"https:\/\/zxi.mytechroad.com\/blog\/wp-json\/wp\/v2\/posts\/7814\/revisions\/7816"}],"wp:attachment":[{"href":"https:\/\/zxi.mytechroad.com\/blog\/wp-json\/wp\/v2\/media?parent=7814"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/zxi.mytechroad.com\/blog\/wp-json\/wp\/v2\/categories?post=7814"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/zxi.mytechroad.com\/blog\/wp-json\/wp\/v2\/tags?post=7814"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}