面试题 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;
    }
};

 

posted @ 2021-03-09 14:17  小码农2  阅读(96)  评论(0)    收藏  举报