洛谷 P1182 数列分段 Section II 二分详细讲解

根据题意可以看出,我们二分的,每段和的最大值的,左边界为数组中最大的一个数,右边界为所有数之和。

我们可以二分这个每段和的最大值,找出满足m段的最小值

根据图来理解代码的注解

cpp 复制代码
const int N = 1e5 + 10;


int n,m;
int a[N];

bool check(int x)
{
	int cnt = 0,sum = 0;//段数,每段的总和
	for (int i = 1;i <= n;i ++)
	{
		if (sum + a[i] <= x) sum += a[i];
		else cnt ++,sum = a[i];
	}
	cnt ++;//记录最后一段
	return cnt > m;//段数>m,说明当前这个最大值偏小
}

void solve()
{
	cin >> n >> m;
	int maxn = 0,sum = 0;
	for (int i = 1;i <= n;i ++) 
		cin >> a[i],maxn = max(maxn,a[i]),sum += a[i];
	
	int l = maxn - 1,r = sum + 1;//根据题意可以看出,左边界为maxn,右边界为sum。这样写是为了将取值范围扩大,避免边界出错
	while(l + 1 != r)
	{
		int mid = l + r >> 1;//二分最大值
		if (check(mid)) l = mid;//mid偏小
		else r = mid;
	}


	cout << r << endl;//输出边界线的右边

	
		
} 
相关推荐
大熊背5 小时前
如何利用Lv值实现三级降帧
算法·自动曝光·lv·isppipeline
大尚来也6 小时前
驾驭并发:.NET多线程编程的挑战与破局之道
java·前端·算法
向阳而生,一路生花6 小时前
深入浅出 JDK7 HashMap 源码分析
算法·哈希算法
君义_noip6 小时前
信息学奥赛一本通 4150:【GESP2509七级】⾦币收集 | 洛谷 P14078 [GESP202509 七级] 金币收集
c++·算法·gesp·信息学奥赛·csp-s
Ricky_Theseus6 小时前
静态链接与动态链接
c++
摸个小yu6 小时前
【力扣LeetCode热题h100】链表、二叉树
算法·leetcode·链表
汀、人工智能6 小时前
[特殊字符] 第93课:太平洋大西洋水流问题
数据结构·算法·数据库架构·图论·bfs·太平洋大西洋水流问题
ZPC82107 小时前
rviz2 仿真控制器与真实机器人切换
人工智能·算法·机器人
澈2077 小时前
双指针,数组去重
c++·算法
小辉同志7 小时前
207. 课程表
c++·算法·力扣·图论