奥赛一本通 1436 数列分段 II
1436 数列分段 II
题目大意
将一个正整数序列分成连续的 $m$ 段,使得每段总和的最大值最小。
知识要点
二分
解题思路
二分枚举总和的最大值 $s$,在每段总和不超过 $s$ 的前提下尽可能的少分段。
参考代码
#include <bits/stdc++.h>
using namespace std;
int n, m, a[100005];
bool check(int s) {
int sum = 0, cnt = 1;
for(int i = 0; i < n; i++) {
if(sum + a[i] <= s) sum += a[i]; //合并到上一段
else sum = a[i], cnt++; //新开一段
if(sum > s || cnt > m) return 0; //注意一个数单独一段也不合法的情况
}
return 1;
}
int main() {
scanf("%d%d", &n, &m);
for(int i = 0; i < n; i++) scanf("%d", &a[i]);
int l = 0, r = 1e9, s;
while(l < r) {
s = (l + r) / 2;
if(check(s)) r = s;
else l = s + 1;
}
printf("%d\n", l);
return 0;
}

浙公网安备 33010602011771号