例题一 奶牛晒衣服:link
题目描述
对于给定的一个长度为 n 的正整数数列 ,现在将其分成 m 段,并要求每段连续,且每段和的最大值最小。
输入格式
第 1 行包含两个正整数 。
第 2 行包含 i 个空格隔开的非负整数 a i a_i ai 。
输出格式
仅包含一个正整数,即每段和最大值最小为多少。
样例
样例输入
5 3
4 2 4 5 1
样例输出
6
数据范围与提示
对于 20% 的数据,n<=5。
对于 50% 的数据,n<=1000。
对于 100% 的数据, 1 < = m , n < = 1 0 5 1<=m,n<=10^5 1<=m,n<=105, a i a_i ai 之和不超过 1 0 9 10^9 109。
思路:
此题出现了一个“最大值最小”的字眼,这种就是单调性最常见的特征之一。(摘自教材上)
简单来说,对于这一种题目,我们关心数据值域,
如果太大了,直接考虑用二分。
设x为最大值的最小值,即每一段都要<=x,
那我们寻找一个x满足分段的个数不超过m,
然后将满足条件的所有值中取一个min就是最优解。
#include <cstdio>
#include <iostream>
using namespace std;
const int N = 1e5 + 10;
int n, m, a[N];
bool check(int x)
{
int ans = 1, tot = 0;
for(int i = 1; i <= n; i++)
{
if(tot + a[i] > x)
{
ans++, tot = a[i];
if(a[i]>x) return 0;
}
else tot += a[i];
}
return ans <= m;
}
int main()
{
scanf("%d%d", &n, &m);
for(int i = 1; i <= n; i++) scanf