哈罗,我们继续学习二分的内容。
我们二分可以在数组中进行查找,也可以在各种结构内进行查找,难道我们的二分只能用在查找上么?
我们这节课就来学习进阶的二分。
二分解决问题
二分不仅可以二分位置,还可以解决一些实际问题。
【*1下界】
二分答案的下界的概念是:最大的尽量小
我们在前面的下界是:
while(l < r)
{
int m = (l + r) / 2;
if (a[m] <= x) l = m + 1;
else r = m;
}
return l;
现在我们怎样来检验它是否满足要求呢?这个我们就需要一个子程序来检验情况。
【*2】下界例题
(1)
等级:菜鸟级
星级:3星
知识点:二分下界
Farmer John是一个精明的会计师。他意识到自己可能没有足够的钱来维持农场的运转了。他计算并记录下了接下来 N (1 ≤ N≤ 100,000) 天里每天需要的开销。Farmer John打算为连续的M(1 ≤ M≤ N) 个财政周期创建预算案,他把一个财政周期命名为一个fajo月。每个fajo月包含一天或连续的多天,每天都被恰好包含在一个fajo月里。
约翰的目标是合理安排每个fajo月包含的天数,使得开销最多的fajo月的开销尽可能少。
这道题我们可以把代码分成几个部分哈,1.check检查函数
2.输入
3.二分+check检验
现在我们来看看怎么写,首先是第1部分,check检查函数,这也是代码最核心的部分。
我们想一下,加入我们现在假设答案是x,也是check传的参数。如果是x,我们怎样来检验x是否成立呢?
既然x是开销最大的月,那么我们可以定义一个money变量来存放每个月的开销,在定义一个cnt来存放有多少个fajo月。
最后满足cnt<=m。
我们既然知道了这些,当然代码就可以写出来。x是最大的开销,所以money不大于x就继续存放,否则就cnt++;并将money设为w[i]。
所以cheak就是:
bool cheak (int x)
{
int cnt = 1, mny = 0;