洛谷P1182 數列分段 Section II

2021-08-27 18:57:21 字數 1424 閱讀 1701

對於給定的乙個長度為n的正整數數列a-ia−i,現要將其分成m(m≤n)m(m≤n)段,並要求每段連續,且每段和的最大值最小。

關於最大值最小:

例如一數列4 2 4 5 142451要分成33段

將其如下分段:

[4 2][4 5][1][42][45][1]

第一段和為66,第22段和為99,第33段和為11,和最大值為99。

將其如下分段:

[4][2 4][5 1][4][24][51]

第一段和為44,第22段和為66,第33段和為66,和最大值為66。

並且無論如何分段,最大值不會小於66。

所以可以得到要將數列4 2 4 5 142451要分成33段,每段和的最大值最小為66。

輸入格式:

第11行包含兩個正整數n,m。

第22行包含nn個空格隔開的非負整數a_iai​,含義如題目所述。

輸出格式:

乙個正整數,即每段和最大值最小為多少。

輸入樣例#1:

5 3

4 2 4 5 1

輸出樣例#1:

6
對於20\%20%的資料,有n≤10n≤10;

對於40\%40%的資料,有n≤1000n≤1000;

對於100\%100%的資料,有n≤100000,m≤n, a_in≤100000,m≤n,ai​之和不超過10^9109。

解法:二分答案

要找到滿足每段和的最大值最小的數。

定義c(d):能找到每段和的最大值小於等於d =>等價於 每一段的和都小於等於d

我們可以貪心的來找,每次都盡量找盡量多的並且和小於d的為一段

如果最後找到的段數小於所需要的段數,則說明存在

因為我們可以拆分任意一段使得段數增加

如果可以r=mid 反之l=mid

最後r即為最後的答案。

然而這樣以後還是wa了乙個點。

最後發現沒有考慮到下界最小必須是最大的那個陣列元素。

那麼我們直接在讀入的時候處理上下界即可(上界為所有數的和)

ps.此外,下界設為0也可以,只需要在判斷sum大小的時候判斷返回false。

#include using namespace std;

const int maxn = 2e5 + 10;

int loc[maxn];

int a, b;

bool c(int mid)

return i <= b;

}int main()

for(int i = 0; i < 100; i++)

cout << r << endl;

return 0;

}

洛谷 P1182 數列分段

這是一道典型的二分答案問題 最大值最小,最小值最大 關鍵是對於細節的處理。二分的框架 l max,r sum while l r else l m 1 cout 二分的框架是普遍使用的,關鍵是檢驗函式的設計,此處的檢驗函式的含義為 是否存在一種合法的劃分,使得每段的最大值都不大於m。設計好了檢驗函式...

洛谷P1182數列分段

對於給定的乙個長度為n的正整數數列a i 現要將其分成m m n 段,並要求每段連續,且每段和的最大值最小。關於最大值最小 例如一數列4 2 4 5 1要分成3段 將其如下分段 4 2 4 5 1 第一段和為6,第2段和為9,第3段和為1,和最大值為9。將其如下分段 4 2 4 5 1 第一段和為4...

洛谷 P1182數列分段Section II

對於給定的乙個長度為n的正整數數列a i 現要將其分成m m n 段,並要求每段連續,且每段和的最大值最小。關於最大值最小 例如一數列4 2 4 5 1要分成3段 將其如下分段 4 2 4 5 1 第一段和為6,第2段和為9,第3段和為1,和最大值為9。將其如下分段 4 2 4 5 1 第一段和為4...