面试题 08.13. 堆箱子(三维最长递增子序列)
堆箱子。给你一堆n个箱子,箱子宽 wi、深 di、高 hi。箱子不能翻转,将箱子堆起来时,下面箱子的宽度、高度和深度必须大于上面的箱子。实现一种方法,搭出最高的一堆箱子。箱堆的高度为每个箱子高度的总和。
输入使用数组[wi, di, hi]表示每个箱子。
示例1:
输入:box = [[1, 1, 1], [2, 2, 2], [3, 3, 3]]
输出:6
示例2:
输入:box = [[1, 1, 1], [2, 3, 4], [2, 6, 7], [3, 4, 5]]
输出:10
这题有点像三维的最长递增子序列,但是有一个地方不太像,对于最长上升子序列来说,我们主要有动态规划O(N²)和贪心算法O(NlogN),本题的目标是上升子序列的最大数据总和,而并非序列长度。所以我们只能考虑O(N^2)的方法。
(因为前面说过O(NlogN)的不能保证序列的准确性。
思路
第一点需要明白的是,我们先对box数组按照一个维度进行排序,得到sorted_box序列,那么最终答案的序列就一定是sorted_box序列的某个子序列(这点很重要)。那么之后我们只需要找到这个总高度最大的子序列。
设dp[i]表示以第i个箱子为结尾的上升子序列的最大总高度。
class Solution { public: int pileBox(vector<vector<int>>& box) { int n = box.size(); vector<int> dp(n,0); // 按第一维排序 sort(box.begin(),box.end(),[](vector<int> &temp1, vector<int> &temp2){ return temp1[0] < temp2[0]; }); int maxnum = 0; for(int i = 0; i < n; i++){ dp[i] = box[i][2]; maxnum = max(maxnum,box[i][2]); for(int j = 0; j < i; j++){ if(box[i][0] > box[j][0] && box[i][1] > box[j][1] && box[i][2] > box[j][2]){ dp[i] = max(dp[i],dp[j] + box[i][2]); maxnum = max(maxnum,dp[i]); } } } return maxnum; } };
浙公网安备 33010602011771号