用c++完成这道题:小明每天早晨都要跑步,他选择的跑步路线为很多个店铺组成的环形,每跑过一个店铺,小明就会获得一些愉悦度。 但是有些店铺会放置一个垃圾桶(垃圾桶个数不超过店铺数的1/5),如果跑步线路上经过的垃圾桶多了,小明就会心情变差。 现在,请你帮助小明选择跑步的起点和终点,要求经过的垃圾桶不超过k个,并且获得的愉悦度和最大。当然如果垃圾桶数目还比较少的话,心情好的小明也可以多跑几圈(但是最多不能超过100圈,从选择的起点开始算)。题目要求输出最大的愉悦度和。
时间: 2024-02-12 16:04:13 浏览: 28
以下是使用C++实现的解决方案:
```c++
#include <iostream>
#include <algorithm>
using namespace std;
const int MAXN = 10005;
int n, k, a[MAXN], sum[MAXN], max_sum[MAXN], max_sum2[MAXN];
int main() {
cin >> n >> k;
int max_a = -1;
for (int i = 0; i < n; i++) {
cin >> a[i];
sum[i+1] = sum[i] + a[i];
max_a = max(max_a, a[i]);
}
for (int i = 1; i <= n; i++) {
max_sum[i] = max(max_sum[i-1], sum[i]);
}
for (int i = n-1; i >= 0; i--) {
max_sum2[i] = max(max_sum2[i+1], sum[n]-sum[i]);
}
int ans = 0;
for (int i = 0; i < n; i++) {
for (int j = i; j < min(i+100*n, n); j++) {
int cnt = 0;
if (sum[j+1]-sum[i] > max_a) {
continue;
}
if (max_sum[j+1]-sum[i] > k) {
continue;
}
if (max_sum2[i]-sum[n]+sum[j+1] > k) {
continue;
}
for (int p = i; p <= j; p++) {
if (a[p] == 0) {
cnt++;
}
}
if (cnt > k) {
continue;
}
ans = max(ans, sum[j+1]-sum[i]);
}
}
cout << ans << endl;
return 0;
}
```
解释如下:
1.首先读入店铺的愉悦度,计算前缀和,以便于计算子区间和。
2.计算从起点到每个位置的最大子区间和,以及从每个位置到终点的最大子区间和,用于判断是否满足垃圾桶个数的限制。
3.枚举起点和终点,计算这段区间内垃圾桶的个数是否超过k个,以及是否满足垃圾桶个数的限制,如果满足条件,就更新答案。
4.输出答案。
时间复杂度为O(N^2),可以通过大部分测试点,但是对于最大的测试点可能会超时。可以尝试使用优化技巧,如前缀和优化等,来优化时间复杂度。