# 1011. Capacity To Ship Packages Within D Days

**<font color=red>难度: Medium</font>**

## 刷题内容

> 原题连接

* https://leetcode.com/problems/capacity-to-ship-packages-within-d-days/

> 内容描述

```
A conveyor belt has packages that must be shipped from one port to another within D days.

The i-th package on the conveyor belt has a weight of weights[i].  Each day, we load the ship with packages on the conveyor belt (in the order given by weights). We may not load more weight than the maximum weight capacity of the ship.

Return the least weight capacity of the ship that will result in all the packages on the conveyor belt being shipped within D days.

 

Example 1:

Input: weights = [1,2,3,4,5,6,7,8,9,10], D = 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

Note that the cargo must be shipped in the order given, so using a ship of capacity 14 and splitting the packages into parts like (2, 3, 4, 5), (1, 6, 7), (8), (9), (10) is not allowed. 
Example 2:

Input: weights = [3,2,2,4,1,4], D = 3
Output: 6
Explanation: 
A ship capacity of 6 is the minimum to ship all the packages in 3 days like this:
1st day: 3, 2
2nd day: 2, 4
3rd day: 1, 4
Example 3:

Input: weights = [1,2,3,1,1], D = 4
Output: 3
Explanation: 
1st day: 1
2nd day: 2
3rd day: 3
4th day: 1, 1
 

Note:

1 <= D <= weights.length <= 50000
1 <= weights[i] <= 500
```

## 解题方案

> 思路 1
******- 时间复杂度: O(N * lg(sum(weights) - max(weights))******- 空间复杂度: O(1)******

开始的时候我题目没看清楚，诶，对于第一个例子。
```Note that the cargo must be shipped in the order given, 
so using a ship of capacity 14 and splitting the packages into parts like 
(2, 3, 4, 5), (1, 6, 7), (8), (9), (10) is not allowed.
```

如果可以不按照顺序来ship的话那题目就难很多了

这样题目就很简单了：
- 最少需要l = max(weights)，也至少需要l = sum(weights) // D，这是毋庸置疑的
- 最多也只需要r = sum(weights)，这是毋庸置疑的
- 对于一个weight, 我们可以通过模拟来知道是否可以满足
- 对于这种weight，我们可以采用二分，从l到r二分

```python
class Solution:
    def shipWithinDays(self, weights: List[int], D: int) -> int:
        l, r = max(max(weights), sum(weights) // D), sum(weights)
        while l < r:
            mid = l + ((r-l) >> 1)
            days, sums, works = 1, 0, True
            for w in weights:
                if w > mid:
                    works = False
                    break
                if sums + w > mid:
                    days += 1
                    sums = 0
                sums += w
            if works and days <= D:
                r = mid
            else:
                l = mid + 1
        return l
```

第 [410题](https://leetcode.com/problems/split-array-largest-sum/) 也可以用同样的方法解决























