對於給定的乙個長度為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,第2段和為6,第3段和為6,和最大值為6。
並且無論如何分段,最大值不會小於6。
所以可以得到要將數列4 2 4 5 1要分成3段,每段和的最大值最小為6。
輸入格式:
輸入檔案divide_b.in的第1行包含兩個正整數n,m,第2行包含n個空格隔開的非負整數a[i],含義如題目所述。
輸出格式:
輸出檔案divide_b.out僅包含乙個正整數,即每段和最大值最小為多少。
輸入樣例#1:
5 34 2 4 5 1
輸出樣例#1:
6
對於20%的資料,有n≤10;
對於40%的資料,有n≤1000;
對於100%的資料,有n≤100000,m≤n, a[i]之和不超過10^9。
很明顯是一道二分題,二分最小化的最大值。
#include#include#include#include#include#includeusing namespace std;
int n,m;
bool p(0);
int a[1000005];
int l=0,r=0;
int main()
//二分範圍為數列中的最大值到數列之和(因為要找最大和的最小值)
while(lmid)
else
if(sum==mid)
if(i==n&&summ)
l=mid+1;
if(times<=m)
r=mid;//r不能設成mid-1,因為times==m時,二分的mid可能就是正確答案!所以下一次二分的區間應包含mid!
}printf("%d\n",r);
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 第...