• LC 面试题 08.13. Pile Box LCCI


    link

     题解:

    按高度升序排序,若高度相同,按宽度降序排序。到i后,用线段树找w,d 在[0,0]-[wi-1,di-1]的最大值,更新此节点。

    class Solution {
    public:
        unordered_map<int,int> seg[3010<<2];
        int qx1,qy1,qx2,qy2;
        int x,y,val;
        int n;
        int cur;
        int queryx(int idx, int xleft, int xright){
            if(xleft>xright || qx1>xright || qx2<xleft) return 0;
            if(qx1<=xleft && qx2>=xright){
                int res=queryy(idx,0,0,n);
                return res;
            }
    
            int mid=(xleft+xright)/2;
            int l=queryx(idx*2+1,xleft,mid);
            int r=queryx(idx*2+2,mid+1,xright);
            return max(l,r);
        }
        int queryy(int idx, int idy, int yleft, int yright){
            if(qy1>yright || qy2<yleft) return 0;
            if(qy1<=yleft && qy2>=yright) return seg[idx][idy];
    
            int mid=(yleft+yright)/2;
            int l=queryy(idx,idy*2+1,yleft,mid);
            int r=queryy(idx,idy*2+2,mid+1,yright);
            return max(l,r);
        }
    
        void updatex(int idx, int xleft, int xright){
            if(xleft>xright || x<xleft || x>xright) return;
            if(xleft==xright){
                updatey(idx,xleft,xright,0,0,n);
                return;
            }
            int mid=(xleft+xright)/2;
            updatex(idx*2+1,xleft,mid);
            updatex(idx*2+2,mid+1,xright);
            updatey(idx,xleft,xright,0,0,n);
        }
    
        void updatey(int idx, int xleft, int xright, int idy, int yleft, int yright){
            if(yleft>yright || y<yleft || y>yright) return;
            if(yleft==yright){
                if(xleft==xright) {
                    seg[idx][idy]=val;
                }
                else seg[idx][idy]=max(seg[idx*2+1][idy],seg[idx*2+2][idy]);
                return;
            }
            int mid=(yleft+yright)/2;
            updatey(idx,xleft,xright,idy*2+1,yleft,mid);
            updatey(idx,xleft,xright,idy*2+2,mid+1,yright);
            seg[idx][idy]=max(seg[idx][idy*2+1],seg[idx][idy*2+2]);
        }
    
        int pileBox(vector<vector<int>>& box) {
            unordered_map<int,int> wid;
            unordered_map<int,int> did;
            sort(box.begin(),box.end(),[](vector<int>& v1, vector<int>& v2){
                return v1[0]<v2[0];
            });
            n=box.size();
            for(int i=0;i<n;i++){
                if(i==0) wid[box[i][0]]=1;
                else {
                    if(box[i][0]>box[i-1][0]) wid[box[i][0]]=i+1;
                }
            }
            sort(box.begin(),box.end(),[](vector<int>& v1, vector<int>& v2){
                return v1[1]<v2[1];
            });
            for(int i=0;i<n;i++){
                if(i==0) did[box[i][1]]=1;
                else {
                    if(box[i][1]>box[i-1][1]) did[box[i][1]]=i+1;
                }
            }
            sort(box.begin(),box.end(),[](vector<int>& v1, vector<int>& v2){
                return v1[2]==v2[2]?v1[0]>v2[0]: v1[2]<v2[2];
            });
          
            int res=0;
            vector<int> dp(n,0);
            for(int i=0;i<n;i++){
                qx1=0;
                qy1=0;
                qx2=wid[box[i][0]]-1;
                qy2=did[box[i][1]]-1;
                int q=queryx(0,0,n);
                dp[i]=q+box[i][2];
                res=max(res,dp[i]);
                x=wid[box[i][0]];
                y=did[box[i][1]];
                val=dp[i];
                cur=i;
                updatex(0,0,n);
            }
            return res;
        }
    
       
    };
  • 相关阅读:
    51nod 1494 选举拉票 | 线段树
    51nod 1295 XOR key | 可持久化Trie树
    Codeforces 438D (今日gg模拟第二题) | 线段树 考察时间复杂度的计算 -_-|||
    51nod 1563 坐标轴上的最大团(今日gg模拟第一题) | 线段覆盖 贪心 思维题
    良心的可持久化线段树教程
    51nod 1593 公园晨跑 | ST表(线段树?)思维题
    51nod 1595 回文度 | 马拉车Manacher DP
    51nod 1522 上下序列
    胡小兔的OI日志3 完结版
    51nod 1510 最小化序列 | DP 贪心
  • 原文地址:https://www.cnblogs.com/FEIIEF/p/12970710.html
Copyright © 2020-2023  润新知