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

	
		
} 
相关推荐
星夜98223 分钟前
C++回顾 Day6
开发语言·数据结构·c++·算法
UpUpUp……2 小时前
C++复习
开发语言·c++·笔记
BC的小新2 小时前
C++ Stack&Queue
c++
charlie1145141913 小时前
从C++编程入手设计模式1——单例模式
c++·单例模式·设计模式·架构·线程安全
asom224 小时前
LeetCode Hot100(矩阵)
算法·leetcode·矩阵
菠萝014 小时前
分布式CAP理论
数据库·c++·分布式·后端
蒟蒻小袁4 小时前
力扣面试150题--二叉树的右视图
算法·leetcode·面试
一块plus4 小时前
当 Bifrost 与 Hydration 携手:Gigadot 能为 Polkadot DeFi 带来哪些新可能?
算法·架构
进击的小白菜4 小时前
LeetCode 215:数组中的第K个最大元素 - 两种高效解法详解
java·算法·leetcode
写个博客6 小时前
代码随想录算法训练营第五十三天
算法