二分法查找
https://baijiahao.baidu.com/s?id=1669750553177807262&wfr=spider&for=pc
LCP 12. 小张刷题计划 https://leetcode-cn.com/problems/xiao-zhang-shua-ti-ji-hua/
这里一开始,是从T=0开始慢慢往上加,最后超时。
如果用二分法:计算T最大值,取中间值 ,计算m,如果m<规定天数,说明这个T时间不够,就取右半边。m>=规定天数,说明T偏大了,取左半边。取到合适T了,但不一定是最小的。下次边界值保留这个,多次循环看看。~
T最大值:花费时间数组累加
int minTime(int* time, int timeSize, int m){
if (timeSize <= m) {
return 0;
}
int max_T = 0;
// 一共有几天
int day_count = m;
// 每天最短做题时间
int day_T = 1;
// 可以求助小杨的次数,最多就是天数,而且一天一次可以保证时间最短。
int yang_count = timeSize;
int i, j;
// 一天内能做的题,时间总和<T,且可以提问(-max)。
int day_sum;
// 一天内能做的题, 其中的最大值
int day_max;
int tag = 0;
for (i = 0; i < timeSize; i++) {
max_T += time[i];
}
// printf("max_T=%d\n",max_T);
// 二分法求T
int T_left = 0;
int T_right = max_T;
int T_mid = (T_left + T_right) / 2;
// 标记每次循环符合要求T的最小值
int min_T = -1;
while (1) {
day_count = m;
tag = 0;
//printf("-----------\n");
//printf("now mid_T=%d\n",T_mid);
for (i = 0; i < timeSize;) {
day_sum = time[i];
day_max = time[i];
// 真正的做题时间,小于这个值,就还能试试多做一题。
//printf("time[%d] = %d\n",i,time[i]);
while ((day_sum - day_max) <= T_mid && i <= timeSize - 1) {
if (i == timeSize - 1) {
// 如果timeSize-1走进了循环,说明是符合要求,可以算在这一天内的。
tag = 1;
break;
}
i++;
day_max = (day_max > time[i]) ? day_max : time[i];
day_sum += time[i];
//printf("time[%d] = %d\n",i,time[i]);
}
// 不满足条件了出来,说明一天在当前dat_T,最多做这几题,少一天。
day_count--;
//printf("day_count=%d\n",day_count);
if (day_count == 0 && (i != timeSize - 1 || (day_sum - day_max) > T_mid)) {
// 天数不够,退出
T_left = T_mid + 1;
T_mid = (T_left + T_right) / 2;
//printf("天数不够,T_mid = %d, T_left = %d, T_right = %d\n",T_mid ,T_left,T_right);
break;
}
if (tag) {
// 天数够了,保留这个T_mid值,万一最小呢。
min_T = T_mid;
T_right = T_mid;
T_mid = (T_left + T_right) / 2;
//printf("天数够,T_mid = %d, T_left = %d, T_right = %d\n",T_mid ,T_left,T_right);
break;
}
}
if (T_left >= T_right) {
//printf("??quit\n");
break;
}
}
return min_T;
}

浙公网安备 33010602011771号