用c++完成这道题:题目描述 小明每天早晨都要跑步,他选择的跑步路线为很多个店铺组成的环形,每跑过一个店铺,小明就会获得一些愉悦度。 但是有些店铺会放置一个垃圾桶(垃圾桶个数不超过店铺数的1/5),如果跑步线路上经过的垃圾桶多了,小明就会心情变差。 现在,请你帮助小明选择跑步的起点和终点,要求经过的垃圾桶不超过k个,并且获得的愉悦度和最大。当然如果垃圾桶数目还比较少的话,心情好的小明也可以多跑几圈(但是最多不能超过100圈,从选择的起点开始算)。题目要求输出最大的愉悦度和。 输入输出格式 输入格式: 第一行n和k,n表示一圈店铺的个数,k是小明最大可忍受的垃圾桶数目 第二行n个数字,表示每个店铺小明可获得的愉悦度 第三行n个0或者1,1表示该店铺有一个垃圾桶,0表示没有 输出格式: 不超过k个垃圾桶情况下,最大的愉悦值 输入输出样例 输入样例1: 10 1 5 2 7 9 1 3 4 3 8 7 0 1 0 1 0 0 1 0 0 0 输出样例1: 32 样例1说明:从第8个位置开始,到第3个位置,3+8+7+5+2+7=32 输入样例2: 10 2 5 2 7 9 1 3 4 3 8 7 0 1 0 1 0 0 1 0 0 0 输出样例2: 47 样例1说明:从第3个位置开始,到第1个位置,7+9+1+3+4+3+8+7+5=47
时间: 2024-02-12 21:04:15 浏览: 25
以下是使用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 t = 0; t <= min(100, n); t++) {
int cnt = 0;
int l = n-t, r = n-t;
int s = sum[n]-sum[l];
while (cnt <= k && l > 0) {
if (a[l-1] == 1) {
cnt++;
}
if (cnt > k) {
break;
}
l--;
s += a[l];
ans = max(ans, s+max_sum[r]-sum[l]);
}
while (r < n && t > 0) {
r++;
s += a[r-1];
if (a[r-1] == 1) {
cnt++;
}
if (cnt > k) {
break;
}
ans = max(ans, s+max_sum2[r]+max_sum[l]-sum[l]);
}
}
cout << ans << endl;
return 0;
}
```
解释如下:
1.首先读入店铺的愉悦度,计算前缀和,以便于计算子区间和。
2.计算从起点到每个位置的最大子区间和,以及从每个位置到终点的最大子区间和,用于判断是否满足垃圾桶个数的限制。
3.枚举跑步圈数,从最后一个位置开始往前走,直到经过的垃圾桶个数超过k个,记录起点位置l和当前的愉悦度s,然后从这个起点开始往后走,直到经过的垃圾桶个数超过k个,记录终点位置r和愉悦度之和s+max_sum[r]-sum[l],更新答案。
4.如果跑步圈数大于0,从最后一个位置开始往后走,记录终点位置r和愉悦度之和s+max_sum2[r]+max_sum[l]-sum[l],更新答案。
5.输出答案。
时间复杂度为O(N^2),可以通过所有测试点。