二分查找

二分查找

//二分法的标准写法
while (L <= R)
{
	if ()   L = mid;
	else    R = mid;
}

因为a/b是向下取整,所以while(L<R)为二分判断标准时,循环会跳不出,因为当R=L+1时,mid=(L+R)/2=L,会变成死循环。

题目

  • 修路HRBUST-1039
    在这里插入图片描述
  • 解题分析:二分求解,分析时间的范围

最大时间:整条路由一个队来修

最短时间:修整路段中最长的一段路所用的时间,即耗时最长的工程队所用的时间

难点:

判断遍历的路段的长度和前一个相加是否小于猜测的构造队伍最少花的时间

如果是就继续加

如果不是就从这个点重新累加

得到如果按这个预期算总共要用多少支队伍

如果得到的队伍数比给出的队伍数多了就代表预期短了,则扩大左区域,少了就代表比预期长了,则减小右区域

#include <iostream>
#include <algorithm>
#include <cstring>
#include <stdio.h>

#define MAXSIZE 305

using namespace std;   //使用名称空间std

int road[MAXSIZE];

int main()
{
	int find(int L, int R, int m);
	int n, m;
	int T;
	int L = 0, R = 0;        //二分下界L为最长路段,上界R为总长
	int ans = 0;
	int num;
	int max;
	scanf("%d", &T);
	while (T--)
	{
		num = 0;
		L = 0;
		R = 0;
		ans = 0;
		memset(road, 0, sizeof(road));
		scanf("%d%d", &m, &n);
		for (int i = 0;i < m;i++)
		{
			scanf("%d", &road[i]);
			R += road[i];
			L = L < road[i] ? road[i] : L;
		}
		//获取二分下界和二分上界
		while (L <= R)
		{//二分查找
			num = find(L, R, m);      //分配的施工队数
			if (num <= n)
			{//二分估计的时间得到的施工队数较少,减小区间右侧
				R = (L + R) / 2 - 1;     //用max进行优化
			}
			else
			{//二分估计时间较小,减小左区间
				L = (L + R) / 2 + 1;
			}
		}
		printf("%d\n", L);
	}


	return 0;
}

int find(int L, int R, int m)
{//返回估计对应的施工队数
	int mid = (L + R) / 2;
	int cnt = 0;
	int res = 0;
	int i = 0;
	while (i < m)
	{
		if (res + road[i] <= mid)
		{
			res += road[i];
			i++;
		}
		else
		{
			res = 0;
			cnt++;
		}
	}
	cnt++;
	return cnt;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值