題目鏈接: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;
}