P1182 數列分段Section II

2021-09-27 03:32:39 字數 1583 閱讀 5679

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

關於最大值最小:

例如一數列42451

4 2 4 5 1

4245

1要分成333段

將其如下分段:

[ 42]

[45][

1]

[4 2][4 5][1]

[42][4

5][1

] 第一段和為6

66,第2

22段和為9

99,第3

33段和為1

11,和最大值為999。

將其如下分段:

[ 4]

[24][

51]

[4][2 4][5 1]

[4][24

][51

] 第一段和為4

44,第2

22段和為6

66,第3

33段和為6

66,和最大值為666。

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

所以可以得到要將數列42451

4 2 4 5 1

4245

1要分成3

33段,每段和的最大值最小為666。

第1

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

第2

22行包含n

nn個空格隔開的非負整數a

ia_i

ai​,含義如題目所述。

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

5 34 2 4 5 16說明

對於20

%20\%

20%的資料,有n≤10

n≤10

n≤10

;對於40

%40\%

40%的資料,有n

≤1000

n≤1000

n≤1000

;對於100

%100\%

100%

的資料,有n

≤100000,m

≤n,a

in≤100000,m≤n, a_i

n≤1000

00,m

≤n,a

i​之和不超過109

10^9

109。

區間最大最小,找二分吧。

先找到最大的數max,作為左邊界。

右邊界就是所有數的和,這樣答案一定在左右邊界裡面。

我們只需每次判斷這個答案是否符合要求即可。

需要注意,如果sub==m,我們能結束嗎?當然不能了。因為我們要找最大值最小啊。如果我們這樣判斷sub>=m,left=mid+1,這樣不是最小的。

#include#include#includeusing namespace std;

int read()

int main(void)

while(left<=right)

} if(sub>m) left=mid+1;

else if(sub<=m) right=mid-1; }

cout<}

P1182 數列分段Section II

二分答案 確定左邊界和右邊界後找中間值,驗證該值是不是不滿足 要找到滿足中最小的那個 不如說是找到不能滿足的最大的那個 1 主要是怎麼寫好judge函式。將數列在保證分段和不超過mid的情況下 盡可能使得段數最少 如果最少段數超過了m,說明滿足最大值最小的 ans 一定比該二分答案大,也就是說mid...

P1182 數列分段 Section II

對於給定的乙個長度為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,和最...

P1182 數列分段 Section II

求最小值的最大,最大值的最小,考慮二分 對於給定的乙個長度為n的正整數數列a i,現要將其分成m m n 段,並要求每段連續,且每段和的最大值最小。輸入格式 第1行包含兩個正整數n,m。第2行包含nn個空格隔開的非負整數a,含義如題目所述。輸出格式 乙個正整數,即每段和最大值最小為多少。輸入樣例 1...