二分法--一个例子

题目描述
shopee的零食柜,有着各式各样的零食,但是因为贪吃,小虾同学体重日益增加,终于被人叫为小胖了,他终于下定决心减肥了,他决定每天晚上去操场跑两圈,但是跑步太累人了,他想转移注意力,忘记痛苦,正在听着音乐的他,突然有个想法,他想跟着音乐的节奏来跑步,音乐有7种音符,对应的是1到7,那么他对应的步长就可以是1-7分米,这样的话他就可以转移注意力了,但是他想保持自己跑步的速度,在规定时间m分钟跑完。为了避免被累死,他需要规划他每分钟需要跑过的音符,这些音符的步长总和要尽量小。下面是小虾同学听的歌曲的音符,以及规定的时间,你能告诉他每分钟他应该跑多少步长?

输入描述:
输入的第一行输入 n(1 ≤ n ≤ 1000000,表示音符数),m(1<=m< 1000000, m <= n)组成,
第二行有 n 个数,表示每个音符(1<= f <= 7)

输出描述:
输出每分钟应该跑的步长

示例1
输入
8 5 6 5 6 7 6 6 3 1

输出
11



//二分答案
//关键是确定二分的上下界
//当m=1时,所有步数总和为上界
//当m=n时,步数的最大值为下界(确定上下界很重要)
#include <bits/stdc++.h>
using namespace std;
 
const int MAXN = 1e6;
 
int a[MAXN+5];
int n,m;
 
void bSearch(int lower,int upper){
    int mid;
    while(lower<=upper){
        mid = (lower+upper)>>1;
        int curSum = 0;
        int cnt = 0;
        bool flag = 1;
        for(int i=0;i<n;){
            while(i<n&&curSum+a[i]<=mid) curSum+=a[i++];
            cnt++;//表示有cnt组加起来小于mid的,若cnt大于mid表示
            //mid太小了,导致组数太多了,所以mid变大,否则,mid
            //增大
            //不满足提前退出
            if(cnt>m) { flag = 0;break;}
            curSum = 0;
        }
        //满足说明可以进一步缩小
        if(flag) upper = mid-1;
        else lower = mid+1;
    }
    printf("%d\n",mid);
}
 
int main() {
    while(~scanf("%d%d",&n,&m)){
        int MAX = 0 ,sum = 0;
        for(int i=0;i<n;i++) {
            scanf("%d", &a[i]);
            MAX = max(MAX, a[i]);
            sum += a[i];
        }
        bSearch(MAX,sum);
    }
    return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值