题目链接:https://www.luogu.com.cn/problem/P1182
题意:给出一个长度为n的数列,将其分为m段,要求每段连续,求得即每段和最大值最小为多少。
思路:
左端点设为数列中最大的数,右端点设为数列的和,对其进行二分
以每次二分出的数mid作为每段和来判断数列可以分为多少段,假设为K段
若K>m,说明分的段数过多,应将mid变大,则使左端点=mid+1
若K<=m,尝试更小的mid, 令右端点=mid-1
代码:
#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const long long mod = 1e9 + 7;
const int INF = 0x3f3f3f3f;
const double PI = 3.141592;
const int e = 1e5;
int n, m;
ll ans, maxn, sum;
ll a[e + 5];
bool jud(ll b){
ll res = 0, num = 1;
for(int i = 0; i < n; i++){
if(res + a[i] > b){
num += 1;
res = a[i];
}
else{
res += a[i];
}
}
if(num <= m) return 1;
return 0;
}
int main()
{
scanf("%d %d", &n, &m);
maxn = 0;
sum = 0;
for(int i = 0; i < n; i++){
scanf("%d", &a[i]);
if(maxn < a[i]) maxn = a[i];
sum += a[i];
}
ll L = maxn, R = sum;
while(L <= R){
ll mid = (L + R) / 2;
if(jud(mid)){
ans = mid;
R = mid - 1;
}
else L = mid + 1;
}
printf("%lld\n", ans);
return 0;
}