解法一:前缀和+二分查找

先求前缀和,遍历每个位置作为起点,用二分查找找到最小费用的终点,不断更新最小费用及其方案队列。

  1. #include <bits/stdc++.h>
  2. using namespace std;
  3. int N, M;
  4. int sum[100005];
  5. int binSearch(int i, int &right) {
  6. right = N;
  7. int left = i;
  8. int mid, val;
  9. while (left < right) {
  10. mid = (left + right) / 2;
  11. val = sum[mid] - sum[i - 1];
  12. if (val >= M) {
  13. right = mid;
  14. } else {
  15. left = mid + 1;
  16. }
  17. }
  18. return sum[right] - sum[i - 1];
  19. }
  20. vector<pair<int, int>> result;
  21. int main() {
  22. ios::sync_with_stdio(false);
  23. cin.tie(0);
  24. cin >> N >> M;
  25. sum[0] = 0;
  26. for (int i = 1; i <= N; ++i) {
  27. cin >> sum[i];
  28. sum[i] += sum[i - 1];
  29. }
  30. int minCost = sum[N];
  31. for (int i = 1; i <= N; ++i) {
  32. int j;
  33. int cost = binSearch(i, j);
  34. if (cost >= M && cost <= minCost) {
  35. if (cost < minCost) {
  36. minCost = cost;
  37. result.clear();
  38. }
  39. result.emplace_back(make_pair(i, j));
  40. }
  41. }
  42. for (auto i:result) {
  43. cout << i.first << "-" << i.second << "\n";
  44. }
  45. }