Leetcode 1011-Capacity To Ship Packages Within D Days(二分,最优化(最大值最小))

Leetcode 1011-Capacity To Ship Packages Within D Days

题干:

传送带上有一堆货物( n n n个)要装载到船上运到对岸,第 i i i个货物的重量是 w e i g h t s [ i ] weights[i] weights[i]

船的载重量为 x x x,船上装在的货物重量之和不会超过船的载重量。货物是按传送带上的顺序依次放在船上的。对于货物 i i i,如果当前船可以继续装它,那么该货物可以装到这个船上;如果当前船装不下了,该货物(及其后面的货物)就要等下一辆船。

一天只有一辆船停在港口。如果想在 d a y s days days天内把货物全部运到对面,求船所需要的最小载重量。

Input: weights = [1,2,3,4,5,6,7,8,9,10], days = 5
Output: 15
Explanation: A ship capacity of 15 is the minimum to ship all the packages in 5 days like this:
1st day: 1, 2, 3, 4, 5
2nd day: 6, 7
3rd day: 8
4th day: 9
5th day: 10

解:

设船的载重量为 x x x。可以得到,船的载重量越大,运送货物所需要的天数越少;船的载重量越少,运送货物所需要的天数越多。所以船的载重量和运送货物所需要的天数是一个单调不递增关系。

所以,可以定义 f ( x ) f(x) f(x)为:以载重量为 x x x的船运送货物,所需要的天数。

又由题,需要限制 f ( x ) ≤ d a y s f(x)\le days f(x)days

所以该题所求的是:满足 f ( x ) ≤ d a y s f(x) \le days f(x)days的条件下的最小 x x x。画图可得求的是左边界。

x x x的取值范围: l e f t = m a x ( w e i g h t s [ i ] ) , r i g h t = ∑ w e i g h t s [ i ] left=max(weights[i]), right=\sum weights[i] left=max(weights[i]),right=weights[i]

int f(vector<int>& weights, int x){
        int cnt = 1, res = x;
        for(int w: weights){
            if(res < w){
                ++cnt;
                res = x;
            }
            res -= w;
        }
        return cnt;
    }
int shipWithinDays(vector<int>& weights, int days) {
        int left = 0, right = 0;
        for(int w: weights){
            left = max(left, w);
            right += w;
        }
        right += 1; //因为是右开区间
        int ans = right;

        while(left < right){
            int mid = left + ((right - left) >> 1);
            int d = f(weights, mid);
            if(d <= days){
                ans = mid;
                right = mid;
            }
            else if(d > days) left = mid + 1;
        }
        return ans;
    }
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值