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

	
		
} 
相关推荐
apcipot_rain10 小时前
C++转Java日记(03)
java·开发语言·c++
布莱克60510 小时前
C++ 中 map 的 insert 与 emplace:key 已存在时会覆盖吗?
开发语言·数据结构·c++·算法·map
xys_67811 小时前
深挖C++:类和对象(中)
开发语言·c++
D e re k ZH13 小时前
C++ 系统学习手记:从语法细节到工程实践
开发语言·数据结构·c++·算法
石小石Orz14 小时前
AI 正在蚕食我们的编码能力
前端·后端·算法
xiaoye-duck14 小时前
《C++ 项目:手写大模型接入 SDK》Ollama接口设计(上):初始化、全量响应实现和测试
开发语言·网络·c++·语言模型
zaizai100715 小时前
【Effective Modern C++】学习第一章
c++
Fruiticecake15 小时前
C 程序员速通现代 C++(一):lambda、std::function、移动语义与智能指针
c语言·c++
民乐团扒谱机16 小时前
【微实验】NSGA-II(非支配排序遗传算法)——解决多目标优化问题的“自然选择模拟器”
linux·人工智能·算法