数列分段
ybtoj 二分-1-1
题目大意
给出一个序列A,让你把它分成m段,使每段和最大值最小
输入样例
5 3
4 2 4 5 1
输出样例
6
数据范围
1
⩽
M
⩽
N
⩽
1
0
5
1\leqslant M\leqslant N\leqslant 10^5
1⩽M⩽N⩽105
s
u
m
{
A
i
}
⩽
1
0
9
sum\begin{Bmatrix}A_i\end{Bmatrix}\leqslant 10^9
sum{Ai}⩽109
解题思路
二分枚举答案
然后
O
(
n
)
O(n)
O(n)判断
代码
#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
#define ll long long
using namespace std;
ll n, m, l, r, mid, a[100010];
bool check(ll x)//判断
{
ll g = 0, gg = 1;
for (int i = 1; i <= n; ++i)
if (g + a[i] <= x) g += a[i];
else g = a[i], gg++;//新的一段
return gg <= m;
}
int main()
{
scanf("%lld%lld", &n, &m);
for (int i = 1; i <= n; ++i)
{
scanf("%lld", &a[i]);
l = max(l, a[i]);
r += a[i];
}
while(l < r)//二分
{
mid = (l + r)>>1;
if (check(mid)) r = mid;
else l = mid + 1;
}
printf("%lld", l);
return 0;
}