洛谷 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;
}

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