二分查詢求最大值最小化(最小值最大化)問題

2021-08-21 12:47:43 字數 3335 閱讀 1759

題目描述

這項比賽將在一條筆直的河道中進行,河道中分布著一些巨大岩石。組委會已經選擇好了兩塊岩石作為比賽起點和終點。在起點和終點之間,有 nn 塊岩石(不含起點和終點的岩石)。在比賽過程中,選手們將從起點出發,每一步跳向相鄰的岩石,直至到達終點。

為了提高比賽難度,組委會計畫移走一些岩石,使得選手們在比賽過程中的最短跳躍距離盡可能長。由於預算限制,組委會至多從起點和終點之間移走 mm 塊岩石(不能移走起點和終點的岩石)。

輸入格式:

第一行包含三個整數 l,n,ml,n,m ,分別表示起點到終點的距離,起點和終點之間的岩石數,以及組委會至多移走的岩石數。保證 l \geq 1l≥1 且 n \geq m \geq 0n≥m≥0 。

接下來 nn 行,每行乙個整數,第 ii 行的整數 d_i( 0 < d_i < l)di​(0輸出格式:

乙個整數,即最短跳躍距離的最大值。

輸入樣例#1:

25 5 2 211

1417

21

輸出樣例#1:

4
此題要求最短距離最大,對於最短距離我們知道其範圍是1~l,那麼可以在該單調區間內進行二分查詢不斷縮小範圍。

那麼還需要乙個判斷函式judge來判斷當前距離作為最短距離是否是可行解。如果是可行解,但有可能它不是最優解,那麼因為求最大值我們還需要繼續向其右部區間查詢是否有更優解;如果不是可行解,那麼可行解只可能在其左部區間,二分向左部查詢。

#includeusing namespace std;

int l, n, m;

int a[50001];

bool judge(int x) //判斷該x距離是否是乙個合法解

if (num > m) //需移走的石頭總數超過了m,說明這個距離是非法解

return false;

return true;

}int main()

else

right = mid - 1;

} cout << ans << endl;

return 0;

}

題目描述

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

關於最大值最小:

例如一數列 42451 要分成 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 。

輸入輸出格式

輸入格式:

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

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

輸出格式:

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

輸入樣例#1:

5 3

4 2 4 5 1

輸出樣例#1:

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

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

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

#include#includeusing namespace std;

int n, m; //分m段,則要劃出m-1條線

int a[100001];

bool judge(int x) //x是所有段中的最大值,希望其最小

else

sum += a[i];

} if (line >= m) //所加的線段數超過了要求的m-1條,說明這個最大和是非法解

return false;

return true;

}int main()

int l = max, r = sum, mid; //注意二分的範圍區間!!最小的和是最大的乙個數,最大的和是所有數的總和!!

while (l <= r) //開始二分選擇,合法則向左找還有沒有更優解,不合法則向右找合法解

else

l = mid + 1;

} cout << ans << endl;

return 0;

}

題目描述

有n條繩子,它們的長度分別為li。如果從它們中切割出k條長度相同的

繩子,這k條繩子每條最長能有多長?答案保留到小數點後2位。

輸入格式:

第一行兩個整數n和k,接下來n行,描述了每條繩子的長度li。

輸出格式:

切割後每條繩子的最大長度。

輸入樣例#1:

4 11

8.02

7.43

4.57

5.39

輸出樣例#1:

2.00
使用二分法範圍尋找繩子長度的最優解,分出的k段繩子長度範圍在0~max之間,max是所有繩子長度的最大值。

#include#includeusing namespace std;

int n, k, num = 0;

double a[10001], sum = 0;

bool judge(double x) //x是繩子的長度,期望其最大

double l = 0, r = max+1, mid;

while (l<=r)

else

r = mid-0.01;

} printf("%.2f\n", ans);

return 0;

}

此外這個題還需要注意的是精度問題!

二分 最小化最大值

注意答案的二分性質,必須要滿足在滿足給定條件的所有情況的時候都滿足要求才能更新ans。include using namespace std typedef long long ll inline ll in while c 0 c 9 res res 10 c 48,c getchar retur...

二分搜尋 (最小值最大化和最大值最小化)

有一類常見問題叫做最小值最大化或者最大值最小化。這類問題一般是用二分搜尋來解決。首先二分搜尋解決的問題必須具備單調性這個性質,這是使用二分搜尋的必要條件,我們分析兩個問題。1.最小值最大化 我們假設x為最大的最小值,那麼x 1是滿足條件的,但他並不滿足最大,x 1是不滿足條件的,假設我們左邊界是l,...

二分搜尋的最大值最小化與最小值最大化

求最大值最小化 二分區間 l,r l max l,r 的區間根據題目所定,這邊寫的區間都是下面題目的區間 r sum 二分模板 while l求最小值最大化 二分區間 l,r l 0 l,r 的區間根據題目所定,這邊寫的區間都是下面題目的區間 r a n a 1 二分模板 while l最小值最大化...