洛谷 P1182 数列分段 Section II

题目链接: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;
}

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章