题目链接
题意:要把一个数列分成M端,并要求每段连续,且每段和的最大值最小。并且无论如何分段,最大值不会小于 6。
上代码:
#include <bits/stdc++.h>
using namespace std;
const int N = 100010;
int n, m, ans, l, r, a[N], sum[N];
int check(int x) {
int cnt = 1, now = 0;
for (int i = 0; i < n; ++i) {
if (now + a[i] <= x)
now += a[i];
else {
cnt++;
now = a[i];
}
}
return cnt <= m;
}
int main() {
cin >> n >> m;
for (int i = 0; i < n; ++i) {
cin >> a[i];
l = max(l, a[i]);
r += a[i];
}
while (l <= r) {
int mid = (r + l) / 2;
if (check(mid))
r = mid - 1;
else
l = mid + 1;
}
cout << l << endl;
return 0;
}
题解:看了看题目,没有什么好的思路,就照旧枚举+二分(二分答案)。答案最小是一个元素单独成一个子段,用l不断更新记录。最大的子段就是全数列,于是用r得到全队列和。之后再l和r之间二分答案。遇到可分子段数量多的,说明平均数小了,需要更大的平均数;遇到可分子段少了,说明平均数大了,需要更小的平均数。