二分法查找

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;
}
posted @ 2020-10-23 09:16  ginn123  阅读(97)  评论(0)    收藏  举报