LC 1340. Jump Game V

link

 

 1.dfs+memo:

class Solution {
public:
    int n;
    int maxJumps(vector<int>& arr, int d) {
        n=arr.size();
        vector<int> memo(n,-1);
        int res=0;
       
        for(int i=0;i<n;++i){
            int tmp=dfs(i,arr,d,memo);
            res=max(res,tmp);
        }
        return res;
    }
    
    int dfs(int idx, vector<int>& arr, int d,vector<int> &memo){
        if(memo[idx]!=-1) return memo[idx];
        int cnt=1;
        for(int dis=1;idx+dis<n && dis<=d;++dis){
            if(arr[idx+dis]>=arr[idx]) break;
            cnt=max(cnt,1+dfs(idx+dis,arr,d,memo));
        }
       
        for(int dis=1;idx-dis>=0 && dis<=d;++dis){
            if(arr[idx-dis]>=arr[idx]) break;
            cnt=max(cnt,1+dfs(idx-dis,arr,d,memo));
        }
        return memo[idx]=cnt;
    }
};

 

2. segment tree + down-up dp:

class Solution {
public:
    int n;
    int seg[1001<<2];
    
    int maxJumps(vector<int>& arr, int d) {
        n=arr.size();
        vector<int> rightB(n);
        vector<int> leftB(n);
        stack<int> stk;
        for(int i=0;i<n;i++){
            while(!stk.empty() && arr[i]>=arr[stk.top()]){
                int t=stk.top();
                stk.pop();
                rightB[t]=min(i-1,t+d);
            }
            stk.push(i);
        }
        while(!stk.empty()){
            int t=stk.top();
            stk.pop();
            rightB[t]=min(n-1,t+d);
        }
        
        for(int i=n-1;i>=0;i--){
            while(!stk.empty() && arr[i]>=arr[stk.top()]){
                int t=stk.top();
                stk.pop();
                leftB[t]=max(i+1,t-d);
            }
            stk.push(i);
        }
        while(!stk.empty()){
            int t=stk.top();
            stk.pop();
            leftB[t]=max(0,t-d);
        }
        vector<int> index;
        for(int i=0;i<n;i++) index.push_back(i);
        
        sort(index.begin(),index.end(),[&](int i1, int i2){
            return arr[i1]<arr[i2];
        });
        int res=0;
        for(int i:index){
            int pre=0;
            if(i-1>=leftB[i]){
                pre=query(1,1,n,leftB[i]+1,i);
            }
            if(i+1<=rightB[i]){
                pre=max(pre,query(1,1,n,i+2,rightB[i]+1));
            }
            int tmp=1+pre;
            res=max(res,tmp);
            update(i+1,1,1,n,tmp);
        }
        return res;
    }
    
    void update(int uidx, int idx, int left, int right,int val){
        if(uidx<left || uidx>right) return;
        if(left==right){
            seg[idx]=val;
            return;
        }
        
        int mid=left+(right-left)/2;
        update(uidx,idx<<1,left,mid,val);
        update(uidx,idx<<1|1,mid+1,right,val);
        seg[idx]=max(seg[idx<<1],seg[idx<<1|1]);
    }
    
    int query(int idx, int left, int right, int qleft, int qright){
        if(qleft>right || qright<left) return 0;
        if(qleft<=left && qright>=right) return seg[idx];
        
        int mid=left+(right-left)/2;
        int l=query(idx<<1,left,mid,qleft,qright);
        int r=query(idx<<1|1,mid+1,right,qleft,qright);
        return max(l,r);
    }
    
   
};

 

3. monostack O(n)

class Solution {
public:
    int maxJumps(vector<int>& arr, int d) {
        int n=arr.size();
        arr.push_back(INT_MAX);
        vector<int> dp(n+1,1);
        stack<int> s1,s2;
        for(int i=0;i<=n;i++){
            while(!s1.empty() && arr[i]>arr[s1.top()]){
                int t=s1.top();
                s1.pop();
                if(i-t<=d) dp[i]=max(dp[i],1+dp[t]);
                s2.push(t);
                while(!s1.empty() && arr[s1.top()]==arr[t]){
                    int tmp=s1.top();
                    s1.pop();
                    if(i-tmp<=d) dp[i]=max(dp[i],1+dp[tmp]);
                    s2.push(tmp);
                }
                
                while(!s2.empty()){
                    int tmp=s2.top();
                    s2.pop();
                    if(!s1.empty() && tmp-s1.top()<=d){
                        dp[s1.top()]=max(dp[s1.top()],dp[tmp]+1);
                    }    
                }
                
            }
            s1.push(i);
        }
        int res=1;
        for(int i=0;i<n;i++){
            res=max(res,dp[i]);
        }
        return res;
    }
};

 

4. 3其实就是topo + dp的简化版,复杂版:

class Solution {
public:
    int ind[1000];
    int maxJumps(vector<int>& arr, int d) {
        int n=arr.size();
        vector<vector<int>> adj(n);
        stack<int> stk;
        for(int i=0;i<n;i++){
            while(!stk.empty() && arr[i]>arr[stk.top()]){
                int t=stk.top();
                stk.pop();
                if(i-t<=d){
                    adj[t].push_back(i);
                    ind[i]++;
                }
            }
            stk.push(i);
        }
        while(!stk.empty()) stk.pop();
        for(int i=n-1;i>=0;i--){
            while(!stk.empty() && arr[i]>arr[stk.top()]){
                int t=stk.top();
                stk.pop();
                if(t-i<=d){
                    adj[t].push_back(i);
                    ind[i]++;
                }
            }
            stk.push(i);
        }
        vector<int> dp(n,1);
        queue<int> q;
        for(int i=0;i<n;i++) {
            if(ind[i]==0) q.push(i);
        }
        while(!q.empty()){
            int cur=q.front();
            q.pop();
            for(int v:adj[cur]){
                dp[v]=max(dp[v],dp[cur]+1);
                ind[v]--;
                if(ind[v]==0) q.push(v);
            }
        }
        int res=0;
        for(int i:dp) res=max(res,i);
        return res;
    }
};

 

posted @ 2020-04-27 16:48  feibilun  阅读(119)  评论(0编辑  收藏  举报