解法一:前缀和+二分查找
先求前缀和,遍历每个位置作为起点,用二分查找找到最小费用的终点,不断更新最小费用及其方案队列。
#include <bits/stdc++.h>
using namespace std;
int N, M;
int sum[100005];
int binSearch(int i, int &right) {
right = N;
int left = i;
int mid, val;
while (left < right) {
mid = (left + right) / 2;
val = sum[mid] - sum[i - 1];
if (val >= M) {
right = mid;
} else {
left = mid + 1;
}
}
return sum[right] - sum[i - 1];
}
vector<pair<int, int>> result;
int main() {
ios::sync_with_stdio(false);
cin.tie(0);
cin >> N >> M;
sum[0] = 0;
for (int i = 1; i <= N; ++i) {
cin >> sum[i];
sum[i] += sum[i - 1];
}
int minCost = sum[N];
for (int i = 1; i <= N; ++i) {
int j;
int cost = binSearch(i, j);
if (cost >= M && cost <= minCost) {
if (cost < minCost) {
minCost = cost;
result.clear();
}
result.emplace_back(make_pair(i, j));
}
}
for (auto i:result) {
cout << i.first << "-" << i.second << "\n";
}
}