YbtOj例題:二分1 數列分段
阿新 • • 發佈:2020-08-04
http://noip.ybtoj.com.cn/contest/14/problem/1
雖然這道題是例題,但是它非常的經典。所以我決定寫一寫。
通常,求解”最大值最小“或”最小值最大“一類的問題,都會用到二分演算法。但僅憑這一個條件無法確定使用二分演算法,下面舉幾個栗子
1.
(這是本題)
總的分組數目有限制,二分有判定條件,可以二分。 答案轉化為二分判定
2.
洛谷P4047部落劃分
部落總數有限制,可以二分。 答案轉化為二分判定
3.
洛谷P4447 [AHOI2018初中組]分組
雖然總的組數沒有限制,但我們可以構造出一個單調上升的序列,p[x]表示第x組接下來需要接上的數的大小,它是單調遞增的,我們可以二分 二分查詢
4.
洛谷P1080國王遊戲
這道題就不能二分,因為總錢數沒有限制,我們也構造不出一個單調的幫助我們解題的序列。
回到這道題
#include <bits/stdc++.h> using namespace std; const int N = 1e5 + 5, inf = 0x3f3f3f3f; int n, m, a[N]; int l, r = 0; bool check(int x) { int s = 0, cnt = 1; for (int i = 1; i <= n; i++) { if (s + a[i] <= x) s+= a[i]; else { cnt++; s = a[i]; } } return cnt <= m; } int main() { scanf("%d%d", &n, &m); for (int i = 1; i <= n; i++) { scanf("%d", &a[i]); l = max(l, a[i]); r += a[i]; } while (l < r) {int mid = l + r >> 1; if (check(mid)) r = mid; else l = mid + 1; } printf("%d", l); return 0; }