leetcode(1687) 从仓库到码头运输箱子 (动态规划+单调队列+前缀和)

tip:有史以来碰到的最难做的hard的题了QWQ,好在阿里举办的leetcode第322场周赛ak了hhh,算是找回了点自信。
在这里插入图片描述

题目链接:https://leetcode.cn/problems/delivering-boxes-from-storage-to-ports/description/

题意:在这里插入图片描述

思路:这题一眼dp,设f[i]表示运送前i个箱子需要的最少行程次数,shuffle[i]为一次性运送1到i的箱子需要的行程次数,wi为前i个箱子的重量,则f[i]=min(f[i],f[j]+shuffle[i]-shuffle[j+1]+2),其中j取值为1到i-1,这样的转移时间复杂度是O(N^2)的,因此要考虑优化,f[j]+shuffle[i]-shuffle[j+1]+2可以写为(f[j]-shuffle[j+1])+shuffle[i]+2,只需找出f[j]-shuffle[j+1]的最小值即可,同时要满足i-j<=maxBoxes和w[i]-w[j]<=maxWeight的条件,将该问题转化后就可以套用单调队列的模板了,总体时间复杂度为O(N)

代码

class Solution {
public:
    int f[100005],shuffle[100005];
    long long w[100005];
    int boxDelivering(vector<vector<int>>& boxes, int portsCount, int maxBoxes, int maxWeight) {
        int i=0,last=boxes[i][0];
        while(i<boxes.size()){
            while(i<boxes.size()&&boxes[i][0]==last) shuffle[i+1]=shuffle[i],i++; 
            shuffle[i+1]=shuffle[i]+1;
            if(i<boxes.size()) last=boxes[i][0];
            i++;
        }
        for(int i=1;i<=boxes.size();i++) w[i]=w[i-1]+boxes[i-1][1];
        deque<pair<int,int>> q;
        q.push_back({0,0});
        for(int i=1;i<=boxes.size();i++){
            if(i==1) f[i]=2,q.push_back({f[i]-shuffle[i+1],i});
            else{
                while(q.size()&&((i-q.front().second>maxBoxes)||(w[i]-w[q.front().second]>maxWeight))) q.pop_front();
                f[i]=f[q.front().second]+2+shuffle[i]-shuffle[q.front().second+1];
                while(q.size()&&f[i]-shuffle[i+1]<=q.back().first) q.pop_back();
                q.push_back({f[i]-shuffle[i+1],i});
            }
        }
        return f[boxes.size()];
    }
};
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值