1011. 在 D 天内送达包裹的能力
传送带上的包裹必须在 D 天内从一个港口运送到另一个港口。
传送带上的第 i 个包裹的重量为 weights[i]。每一天,我们都会按给出重量的顺序往传送带上装载包裹。我们装载的重量不会超过船的最大运载重量。
返回能在 D 天内将传送带上的所有包裹送达的船的最低运载能力。
示例 1:
输入:weights = [1,2,3,4,5,6,7,8,9,10], D = 5
输出:15
解释:
船舶最低载重 15 就能够在 5 天内送达所有包裹,如下所示:
第 1 天:1, 2, 3, 4, 5
第 2 天:6, 7
第 3 天:8
第 4 天:9
第 5 天:10
请注意,货物必须按照给定的顺序装运,因此使用载重能力为 14 的船舶并将包装分成 (2, 3, 4, 5), (1, 6, 7), (8), (9), (10) 是不允许的。
示例 2:
输入:weights = [3,2,2,4,1,4], D = 3
输出:6
解释:
船舶最低载重 6 就能够在 3 天内送达所有包裹,如下所示:
第 1 天:3, 2
第 2 天:2, 4
第 3 天:1, 4
示例 3:
输入:weights = [1,2,3,1,1], D = 4
输出:3
解释:
第 1 天:1
第 2 天:2
第 3 天:3
第 4 天:1, 1
题解
二分查找不好理解可以自己画图理解
class Solution {
public:
int shipWithinDays(vector<int>& weights, int D) {
// 真的想不到,很精妙
// 贪心算法加二分查找
/*
依据: 存在一个运载能力的最小值x当运载能力大于x时肯定没问题,当运载能力低于x时候肯定不行,那么这个x就是我们所求的答案
接下来就有两个问题,能解决这两个问题就能用二分查找进行解决
问题一: 怎么确定二分查找的上下边界
问题二: 怎么确定x运载能力的时候能够运完
问题一: 运送能力最低:也就是一个物体运送一天也就是max(weights[i]) 运送能力最高:一天运完 sum(weights[i])
问题二: 因为只能够按照顺序运送,所以可以用贪心算法,贪心策略就是每次运送运载能力内的最多的货
*/
int left=0,right=0;
for(int i=0; i<weights.size();i++) {
left=max(left,weights[i]);
right+=weights[i];
}
int mid=0;
// 左闭右闭
while(right>left) {
mid = left+(right-left)/2;
// cout<<"mid "<<mid<<" ";
if(Check_ability(weights,mid,D)) {
right=mid;
// cout<<"true"<<endl;
} else {
left=mid+1;
// cout<<"false"<<endl;
}
}
return right;
}
bool Check_ability(const vector<int>& weights , int ability ,int D) {
int index=0;
for(int i=0 ; i<=D ; i++) { // 为什么要等于D因为可能再最后一天装好了,所以要多一次进行验证
if(index>=weights.size()) {
return true;
}
int sum=0;
for(index; index<weights.size();index++) {
sum+=weights[index];
if(sum>ability) {
// index--;// 因为break后就没有++操作了 || 这时候index就是下一段的起点
break;
}
}
// cout<<"index: "<<index<<endl;
}
return false;
}
};