洛谷P1182 數列分段 Section II

2021-08-22 19:26:52 字數 1451 閱讀 2750

題目描述

對於給定的乙個長度為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_ia

i ​ ,含義如題目所述。

輸出格式:

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

輸入輸出樣例

輸入樣例#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,a

i ​ 之和不超過 10^910 9 。

就是將二分轉換為判定的裸題,忘了就翻演算法競賽第26頁(注意這種思想經常被用到,需要十分熟練)

注意如果在判斷二分出來的答案是否合法,若有乙個元素的值大於該答案,則必定不合法,因為每個區間都小於該元素。

若不立刻退出,則會把它單獨放在乙個區間,可能會導致返回true,則答案錯誤。

#include

#include

#include

#include

#include

#define n 100000000

using

namespace

std;

int n,m;

int r;

int a[n];

inline

bool calc(int x)

}return group<=m;

}int main()

int l=0;

while(lint mid=(l+r)>>1;

if(calc(mid))r=mid;

else l=mid+1;

} printf("%d",r);

}

洛谷 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...