洛谷 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;//输出边界线的右边

	
		
} 
相关推荐
m沐沐6 小时前
【深度学习】YOLOv2目标检测算法——改进点、网络结构与聚类先验框解析
人工智能·pytorch·深度学习·算法·yolo·目标检测·transformer
不会就选b6 小时前
算法日常・每日刷题--<链表>3
数据结构·算法·链表
geovindu6 小时前
go: Iterative Algorithms
开发语言·后端·算法·golang·迭代算法
Zachery Pole8 小时前
CCF-CSP备战NO.7【队列】
算法
闪电悠米9 小时前
力扣hot100-48.旋转图像-转置翻转详解
算法·leetcode·职场和发展
满天星83035779 小时前
【算法】最长递增子序列(三种解法)
算法
hold?fish:palm9 小时前
kv存储主从复制的设计与实现
c++·redis·后端
啦啦啦啦啦zzzz9 小时前
算法:贪心算法
c++·算法·leetcode·贪心算法
charlie11451419110 小时前
现代C++工程实践 WeakPtr 实战(三):WeakPtrFactory 与「最后成员」惯用法
开发语言·c++·开源项目·现代c++
清泓y11 小时前
RAG 技术
算法·ai