1011-在 D 天内送达包裹的能力

题目

1011. 在 D 天内送达包裹的能力 - 力扣(LeetCode) (leetcode-cn.com)

思路

问题1: 如何判断载重量为load的船至少需要多少天能够运送所有包裹呢?

我们只需要遍历一次weights数组,从第一个元素开始求和,直到和大于load(尽可能把船装满),此时可以确定当前元素之前的元素应该安排在一天运送。我们重置和为0,并添加当前元素(因为当前元素加到前一天导致船超载),继续遍历数组后续元素即可得到所需的天数。

如果某个元素超过了load则结果为无限大(INT_MAX)

问题2:我们如何确定在D天内送完所有包裹需要的船的最小载重量呢?

由于我们已经解决了上一个问题,我们可以将载重量设置为1并逐渐增加进行尝试,直到所需的运输天数刚刚小于等于D。不过该方法可能会超时,我们可以通过二分搜索的方式来更快的找到合适的载重量。

首先我们确定载重量的上下界,上界为所有的货物重量之和,下界为最大的单个货物重量。使用二分搜索,如果当前测试载重量load需要的运输天数大于D,则将搜索下界改为load + 1(因为当前load值必定不会是最终结果)。如果当前测试的load值小于或者等于D,则将搜索上界设置为load, 直到上下界相等,则是我们所求的最终结果。

当运输天数<=D时,当前测试的载重量不一定是最小载重量(但可能是),因此我们还需要尝试减小载重量load进行测试,但由于当前load也可能是最小载重量,因此我们设置上界为load而不是load-1

代码

class Solution {
public:
    int shipWithinDays(vector<int>& weights, int D) {
        int load = 0;
        int i = 0;
        int low = 0;
        int high = 0;

        for(int n : weights) {
            high += n;
            if (n > low) {
                low = n;
            }
        }
        while(high > low) {
            load = (high + low) / 2;
            int day = day_used(load, weights);
            if (day <= D) {
                high = load;    
            } else if (day > D) {
                low = load + 1;
            }
        }
        return high;
    }

    int day_used(int load, vector<int>& weights) {
        int day = 0;
        int current = 0;
        for(int n : weights) {
            if (n > load) {
                return INT_MAX;
            }
            current += n;
            if (current > load) {
                day++;
                current = n;
            }
        }
        if (current > 0) {
            day++;
        }
        return day;
    }
};
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值