第一题:愤怒的牛 loj链接

两道题目都是基础二分的模板题,先看第一题,题意为总共有nnn间牛舍,mmm头牛,要将mmm头牛安排在nnn间牛舍,为防止牛互相攻击,使两头牛之间的最小距离最大最大! 最大!(重要的事情说三遍)
以样例来说明,

5 3
1 2 8 4 9

根据上面的样例,首先对牛舍进行排序,可以得到

1 2 4 8 9

可以有以下几种方案(将牛安排在以下编号的牛舍)
1 2 4 此方案牛与牛最小的距离为1
1 4 8 此方案牛与牛最小的距离为3
1 4 9 此方案牛与牛最小的距离为3
2 4 8 此方案牛与牛最小的距离为2
2 4 9 此方案牛与牛最小的距离为2
……
从以上方案可以看出,就是要尽可能的让最小距离最大。再来看看下面的代码

bool chk(int t){int sum=a[1],ans=1;for(int i=2;i<=n;i++){if(sum+t>a[i]) continue;else{sum=a[i];ans++;}}return ans>=m;
}

通过样例的数据,对照上面的代码不难得到,
t=1的时候,ans=5;
t=2或者t=3都可以满足ans=3;
t>=4的时候,ans=2;
因此,只有当t=2或者t=3才能满足条件(样例共3头牛),显然,t=3才符合题意,那么,怎么确保t尽量取到更大的值呢?
可以这样分析,当ans>m的情况那么一定是二分值太小,而ans<m则是二分值太大,
于是为了让t取到更大的值应该采用if(chk(t)) l=mid,这样求出的二分值更大

while(l<r-1){int mid=(l+r)/2;if(chk(mid)) r=mid;else l=mid;}

如果把chk函数里面的返回值改成 return ans<=m,配上 if(chk(t)) r=mid;else l=mid 这样,表面上看没什么错误,实际上最终求出的二分值是更小的,这是不符合题意的。

第二题:数列分段 loj链接

本题要求将n个整数系列分成指定的m段,每段至少包含一个数,求处所有的分段方法中,各段的和的最大值最小! 最小! 最小!(重要的事情说三遍)
题目还有一个重要的要求,要求每段的数都是连续的,即按照原数的顺序切割成m段。

5 3
4 2 4 5 1

对照样例数据,可以采用如下集中切法:

4 2 | 4 5 | 1 三段之和分别为 6 9 1 ,和的最大值为9
4 | 2 4 | 5 1 三段之和分别为 4 6 6 ,和的最大值为6

以上两种切割的方法都是分成3段,但是,依据题意,更优的切割方法是第二种.
接下来看看本题正确的check函数的写法

bool chk(int x){int sum=0,tot=1;for(int i=1;i<=n;i++){if(sum+a[i]<=x) sum+=a[i];else{tot++;sum=a[i];}}return tot<=m;
}

和第一题一样,考虑到存在tot=m的情况下,其二分值不是最优的(样例中的第1种切割方法),应该尽量让二分值尽可能的小又同时满足tot=m这个前提。
如果tot<=m,说明是二分值偏大,因此可以采用 if(chk(x)) r=mid;else l=mid,这样就可以满足tot=m的同时,二分值最小。

while(l<r-1){int mid=(l+r)/2;if(chk(mid))r=mid;else l=mid;}

需要注意的是,本题的二分算法的初值必须让 l=max(ai)l=max(ai)l=max(ai),r=sum(ai)r=sum(ai)r=sum(ai)。

如果把chk函数里面的返回值改成 return ans>=m,配上 if(chk(t)) l=mid;else r=mid 这样,表面上看没什么错误,实际上最终求出的二分值虽然满足了分成了m段,但是二分值却是更大的,(第一种切割方法就属于这种情况)这是不符合题意的。

第一题完整代码

#include <bits/stdc++.h>
using namespace std;
int n,m,a[100008];
bool chk(int t){int g=a[1],ans=1;for(int i=2;i<=n;i++){if(g+t>a[i]) continue;else{g=a[i];ans++;}}return ans>=m;
}
int main(){scanf("%d%d",&n,&m);for(int i=1;i<=n;i++) scanf("%d",a+i);sort(a+1,a+n+1);int l=a[1],r=a[n];while(l<r-1){int midl=(l+r)>>1;if(chk(midl)) l=midl;else r=midl;}if(chk(l)) printf("%d",l);else printf("%d",r);return 0;}

第二题完整代码

#include <bits/stdc++.h>
using namespace std;
int n,m,a[100005],maxx=-1,cnt;
bool chk(int x){int sum=0,tot=1;for(int i=1;i<=n;i++){if(sum+a[i]<=x) sum+=a[i];else{tot++;sum=a[i];}}return tot<=m;
}
int main(){scanf("%d%d",&n,&m);for(int i=1;i<=n;i++){scanf("%d",a+i);maxx=max(maxx,a[i]);cnt+=a[i];}int l=maxx,r=cnt;while(l<r-1){int mid=(l+r)/2;if(chk(mid))r=mid;else l=mid;}if(chk(l)) printf("%d",l);else printf("%d",r);return 0;}

从两道基础二分算法题谈check函数的写法相关推荐

  1. 我整理了50道经典Java算法题,直接进了字节跳动!!

    写在前面 最近,很多小伙伴都想进入字节跳动这个快速发展的公司,而字节跳动对于算法的要求比较高.于是乎,有些小伙伴问我能否整理一些基础的算法题,帮助他们提升下基础算法能力.我:没问题啊!于是,经过半个多 ...

  2. 130道基础OJ编程题之: 47 ~ 57 道

    130道基础OJ编程题之: 47 ~ 57 道 文章目录 130道基础OJ编程题之: 47 ~ 57 道 0. 昔日OJ编程题: 47. BC50 计算单位阶跃函数 48. BC51 三角形判断 49 ...

  3. java经典100例算法题_10道java经典算法题,每一题都能帮你提升java水平!

    JAVA经典算法题 [程序1] 题目:古典问题:有一对兔子,从出生后第3个月起每个月都生一对兔子,小兔子长到第四个月后每个月又生一对兔子,假如兔子都不死,问每个月的兔子总数为多少? 1.程序分析:兔子 ...

  4. 语言高精度算法阶乘_JavaScript中的算法(附10道面试常见算法题解决方法和思路)...

    https://juejin.im/post/6844903811505455118 Introduction 面试过程通常从最初的电话面试开始,然后是现场面试,检查编程技能和文化契合度.几乎毫无例外 ...

  5. 80道漫画图解算法题汇总(0406版本)

    各位好,本人自2019年1月以来,连续写了80余篇算法题解(主要针对高频面试题),都采用漫画图解的方式,为了大家查阅方便,我对目录进行了汇总,大家有兴趣的可以收藏一下,以备不时之需.(另外,为了感谢大 ...

  6. java求最大公约数_10道java经典算法题,小白必备,每一题都能提升你的java能力...

    JAVA经典算法 跪求关注,祝关注我的人都:身体健康,财源广进,福如东海,寿比南山,早上贵子,从不掉发! 更多java资料可以私信我领取! [程序1] 题目:古典问题:有一对兔子,从出生后第3个月起每 ...

  7. 两道有趣的逻辑推理题

    海盗分金币 问题: 有5个海盗,按照等级从5到1排列.最大的海盗有权提议他们如何分享100枚金币.但其他人要对此表决,如果多数(所有人中的多数)反对,那他就会被杀死.他应该提出怎样的方案,既让自己拿到 ...

  8. 漫画图解python_80道漫画图解算法题汇总

    本文每个链接采用漫画图解的方式,为了大家查阅方便,对目录进行了汇总,大家有兴趣的可以收藏一下,以备不时之需. 01 PART 二分法系列 介绍:二分法自不必说,是面试以及比赛的高频考点,必须掌握. 0 ...

  9. 两道动态规划买股票的题

    T1:给定一个数组 prices ,其中 prices[i] 表示股票第 i 天的价格. 在每一天,你可能会决定购买和/或出售股票.你在任何时候 最多 只能持有 一股 股票.你也可以购买它,然后在 同 ...

最新文章

  1. Latex之WinEdt编辑界面的自动换行
  2. wcf寄宿iis7是的 500错误
  3. python 发邮件 timeout_python发送邮件
  4. IDEA模块(module)的概念和使用_对比Eclipse
  5. python笔记30-docstring注释添加变量
  6. Taro+react开发(100):问答模块07适配
  7. Windows GDI和GDI+编程实例剖析(1)
  8. 零基础带你学习MySQL—自连接(二十一)
  9. Google 已经实现即点即玩,国内 Android 何时跟上?
  10. php相册上传和删除吗,php上传与删除图片的简单范例
  11. ubuntu18.04窗口截图和选区截图快捷键
  12. 谷歌中国发布三国赤壁地图
  13. 2021全国特种设备-R1快开门式压力容器充装模拟考试题库一[安考星]
  14. 微信小程序存在的风险_微信小程序交易存在哪些风险
  15. 合宙Air724 Luat 开发接入ThingsCloud 物联网云平台
  16. 给高特键轴开盖的操作技巧
  17. IT实习生需要做什么?IT实习心得
  18. window系统换为ubuntu系统
  19. Vue3源码阅读指南——计算属性(effectcomputed)
  20. oracle官网下载教程

热门文章

  1. 现代循环神经网络-1.门控循环单元(GRU)【动手学深度学习v2】
  2. javaweb汽车租赁系统springboot+vue+nodejs
  3. ubuntu 16.04 + eigen3 安装
  4. requests.exceptions.ChunkedEncodingError: (‘Connection broken: IncompleteRead(0 bytes read)‘, Incomp
  5. 改编的一个屏幕保护程序
  6. hutool 解读(三)—— IO流
  7. 【调音小栈】普瑞声纳Revelator io24直播关联机架驱动跳线设置教程
  8. PHP源生数据分页显示
  9. Android 沉浸式模式
  10. 基于simulink的离散系统