1 条题解
-
1
暴力枚举:第一个 枚举区间长度,第二个 枚举区间起点,第三个 累加区间和为, 不断取 ,时间复杂度为 , 超时。
考虑优化,由于累加我们可以想到前缀和, 表示的是前 个元素的和, 时间便可快速求解区间和,此时减去一维累加操作,时间复杂度为 , 仍然超时。
继续优化,由于本题要求长度不超过 ,观察发现对于长度为 的区间 ,且必包含元素 最优解即为 减去前 个元素的最小值(会向前多减一个),由局部推广到整体,线性扫描整个数组,求解任意一个区间长度为 的最优解不断取 ,便是最终答案。这一步成其实是将问题转化为滑动窗口求最值问题,时间复杂度为
#include <iostream> using namespace std; const int N = 300010; int n, m; int a[N], s[N]; int q[N]; int res; int main() { cin >> n >> m; for(int i = 1; i <= n; ++ i) { cin >> a[i]; s[i] = s[i - 1] + a[i]; }//求前缀和 int hh = 0, tt = -1; for(int i = 1; i <= n; ++ i) { if(i - q[hh] > m) ++ hh;//由于是用到前m个的最值,所以长度为m+1仍然合法 res = max(res, s[i] - s[q[hh]]); while(hh <= tt && s[q[tt]] >= s[i]) -- tt;//滑动窗口存的是下标,所以额外嵌套s[q[tt]] q[++ tt] = i;//存窗口所有元素的下标 } cout << res << '\n'; return 0; }
- 1
信息
- ID
- 5522
- 时间
- 1000ms
- 内存
- 256MiB
- 难度
- 9
- 标签
- 递交数
- 16
- 已通过
- 3
- 上传者