給定 N 天的花費記錄,需要將這 N 天分成 M 個連續的組(每組代表一個月),每組的花費為該組內天數花費之和。目標是找到一種分組方式,使得所有組中「最大花費」最小化。
這是一個典型的「二分答案」問題:
bool judge(int N, int M, int mid, vector<int> a) {
int sum = 0; // 當前組累計花費
int group = 1; // 已使用組數
for (int i = 0; i < N; i++) {
if (sum + a[i] <= mid) {
sum += a[i]; // 加入當前組
} else {
sum = a[i]; // 開啟新組
group++;
}
}
return group <= M; // 組數不超過 M 則可行
}
#include <iostream>
#include <vector>
using namespace std;
bool judge(int N, int M, int mid, const vector<int>& a) {
int sum = 0, group = 1;
for (int i = 0; i < N; i++) {
if (sum + a[i] <= mid) {
sum += a[i];
} else {
sum = a[i];
group++;
}
}
return group <= M;
}
int main() {
int N, M;
while (cin >> N >> M) {
vector<int> a(N);
int maxVal = 0, sum = 0;
for (int i = 0; i < N; i++) {
cin >> a[i];
maxVal = max(maxVal, a[i]);
sum += a[i];
}
int left = maxVal, right = sum, ans = sum;
while (left <= right) {
int mid = (left + right) >> 1;
if (judge(N, M, mid, a)) {
ans = mid;
right = mid - 1; // 嘗試更小的最大花費
} else {
left = mid + 1; // 需要增大限制
}
}
cout << ans << endl;
}
return 0;
}