题目描述
对于给定的一个长度为 N 的正整数数列 Ai,现要将其分成 M(M≤N) 段,并要求每段连续,且每段和的最大值最小。
关于最大值最小:
例如一数列 4 2 4 5 1 要分成 3 段
将其如下分段:
[4 2][4 5][1]
第 1 段和为 6,第 2 段和为 9,第 3 段和为 1,和最大值为 9。
将其如下分段:
[4][2 4][5 1]
第 1 段和为 4,第 2 段和为 6,第 3 段和为 6,和最大值为 6。
并且无论如何分段,最大值不会小于 6。
所以可以得到,要将数列 4 2 4 5 1 分成 3 段,每段和的最大值最小为 6。
输入
第一行两个整数 N,M。(1≤M≤N≤100,000)
接下来 N 行,每行一个数,表示 Ai。(1≤Ai≤100,000,000)
输出
一个正整数,即每段和最大值最小为多少。
样例输入
5 3
4
2
4
5
1
样例输出
6
数据规模与约定
时间限制:1 s
内存限制:256 M
100% 的数据保证 1≤M≤N≤100,000,1≤Ai≤100,000,000
#include <iostream>
using namespace std;long long n, m, num[1000005], num_max, num_sum;
long long check(long long mid) {long long mmax = 0, cnt = 0;for (int i = 0; i < n; i++) {if (mmax + num[i] == mid) {cnt++;mmax = 0;}else if (mmax + num[i] > mid) {cnt++;mmax = num[i];}else {mmax += num[i];}}if (mmax > 0) {cnt++;}return cnt;
}
int main() {cin >> n >> m;for (int i = 0; i < n; i++) {cin >> num[i];num_max = max(num_max, num[i]);num_sum += num[i];}long long l = num_max, r = num_sum;while (l != r) {long long mid = (l + r) / 2;long long s = check(mid);if (s > m) {l = mid + 1;}else {r = mid;}}cout << l << endl;return 0;
}
版权声明:本站所有资料均为网友推荐收集整理而来,仅供学习和研究交流使用。
工作时间:8:00-18:00
客服电话
电子邮件
admin@qq.com
扫码二维码
获取最新动态