标签:class 个数 关系 输入 代码 思路 pac 而且 pre
输入一个长度为n的整数序列,从中找出一段不超过m的连续子序列,使得整个序列的和最大。
第一行两个数n,m(n,m<=300000)
第二行有n个数(均在int范围内),要求在n个数找到最大子序和。
输出一个数,表示它们的最大子序和。
6 4
1 -3 5 1 -2 3
7
sum来存放前缀和
对于某一个i,我们要找到一个j(i-j<=m),使得sum[i]-sum[j]最大。
假设如果有j1<j2,而且sum[j1]>sum[j2],那么j1可以直接抛弃,也就是在这个j的序列里,必须是单调递增的,所以我们可以用一个单调队列来维护这一关系
实现代码如下:
#include <bits/stdc++.h>
using namespace std;
const int maxn = 300030;
int n, m;
long long a[maxn], sum[maxn], f[maxn], ans;
deque<int> que;
int main() {
cin >> n >> m;
for (int i = 1; i <= n; i ++) {
cin >> a[i];
sum[i] = sum[i-1] + a[i];
}
ans = sum[1];
for (int i = 2; i <= n; i ++) {
while (!que.empty() && sum[que.back()] > sum[i-1]) que.pop_back();
que.push_back(i-1);
if (!que.empty() && que.front() < i-m) que.pop_front();
ans = max(ans, sum[i] - sum[que.front()]);
}
cout << ans << endl;
return 0;
}
标签:class 个数 关系 输入 代码 思路 pac 而且 pre
原文地址:https://www.cnblogs.com/quanjun/p/12266199.html