int hour (int* piles, int pilesSize, int x);
int minEatingSpeed(int* piles, int pilesSize, int h){
int left = 1;
int right = 1000000000 + 1;
while (left < right) {
int mid = left + (right - left) / 2;
if (hour(piles, pilesSize, mid) <= h) {
right = mid;
} else {
left = mid + 1;
}
}
return left;
}
int hour (int* piles, int pilesSize, int x) {
int hours = 0;
for (int i = 0; i<pilesSize; i++) {
hours += piles[i] / x; //有几个小时
if (piles[i] % x > 0) { //剩下不管多少都是一个小时的量,无脑加1
hours++;
}
}
return hours;
}
1011. 在 D 天内送达包裹的能力
本题目标target要求在days天从一个港口到另一个港口。
传送带上的第 i 个包裹的重量为 weights[i]。每一天,我们都会按给出重量(weights)的顺序往传送带上装载包裹。
返回能在 days 天内将传送带上的所有包裹送达的船的最低运载能力,这就是我们需要求的x,运输天数和运载能力成反比,所以可以让f(x)为当前x的运载能力下需要的运输天数,那么f(x)是单调递减的,此时求解最低运载能力就是要求区间的左侧。
返回能在 days 天内将传送带上的所有包裹送达的船的最低运载能力。
按照二分法的做法,能根据天数来求出每天最低的运载量,即这个区间的左侧。
left作为船的最小载重应该是weights数组中元素的最大值,假如磨洋工,那么每次至少得装一件货物走。
那么确定right,righ是最大承载能力。最大承载能力要求在最极限的条件下实现,比如要求一天之内完成,那么这个right就是所有承重之和。
int day (int *weights, int weightsSize, int x);
int shipWithinDays(int* weights, int weightsSize, int days){
int left = 1;
int right = 1; //区间左闭右开
int max = 0;
for (int i=0; i<weightsSize; i++) {
if ( max < weights[i] ) {
max = weights[i];
}
right += weights[i];
}
left = max;
while (left < right) {
int mid = left + (right-left) / 2;
if (day(weights, weightsSize, mid) > days) {
//当天数超过目标,说明量不够,需要加
left = mid + 1;
} else {
right = mid;
}
}
return left; //返回的是载重能力
}
int day (int *weights, int weightsSize, int x) { //x为载货能力
int day = 0;
for (int i = 0; i < weightsSize; ) {
// 尽可能多装货物
int cap = x;
while (i < weightsSize) {
if (cap < weights[i]) break;
else cap -= weights[i];
i++;
}
day++;
}
return day;
}
int array (int *nums, int numsSize, int x); //计算出有多少组
int splitArray(int* nums, int numsSize, int m){ //m为target
int max = 0; //元素最大值为左起点
int sum = 1; //和为右起点
for (int i = 0; i<numsSize; i++) {
if (max < nums[i]) {
max = nums[i];
}
sum += nums[i];
}
int left = max;
int right = sum;
while (left < right) {
int mid = left + (right - left) / 2;
if (array(nums, numsSize, mid) > m) { //需要把mid调大
left = mid + 1;
} else {
right = mid;
}
}
return left;
}
int array (int *nums, int numsSize, int x) { //传入的参数为每组的最大和
int cnt = 1;
int sum = 0;
for (int i = 0; i != numsSize; i++ ) {
if (sum + nums[i] <= x) {
sum += nums[i];
} else if (sum + nums[i] > x){
sum = nums[i];
cnt++;
}
}
return cnt;
}