数列分段
ybtoj 二分-1-1
题目大意
给出一个序列A,让你把它分成m段,使每段和最大值最小
输入样例
5 3
4 2 4 5 1
输出样例
6
数据范围
1⩽M⩽N⩽1051\leqslant M\leqslant N\leqslant 10^51⩽M⩽N⩽105
sum{Ai}⩽109sum\begin{Bmatrix}A_i\end{Bmatrix}\leqslant 10^9sum{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;
}