标签:16px region none cli 前缀 最小值 图片 总结 event
算是一个总结吧!
先来一个模板;
第一行两个数n,m
第二行有n个数,要求在n个数找到最大子序和
6 4 1 -3 5 1 -2 3
7
数据范围:
100%满足n,m<=300000
这个可以算是单调队列优化dp的模板题了吧;
令f[i]表示以i为结尾的连续子序的最大值;
所以, f[i] = min (sum[i] - sum[j]) ( i - m <= j <= i); sum 为前缀和;
即 f[i] = sum[i] - min(sum[j])( i - m <= j <= i);
显然可以用单调队列维护前缀最小值;
代码:
#include <iostream> #include <cstdio> #include <algorithm> #include <cstring> #include <queue> using namespace std; int n, m; int a[300010]; int sum[300010]; deque <int> q; int ans; int main() { cin >> n >> m; for(register int i = 1 ; i <= n ; i ++) { scanf("%d", &a[i]); sum[i] = sum[i-1] + a[i]; } for(register int i = 1 ; i <= n ; i ++) { while(!q.empty() && sum[q.front()] > sum[i]) q.pop_front(); q.push_front(i); while(!q.empty() && i - m > q.back()) q.pop_back(); if(i != 1) { ans = max(ans, sum[i] - sum[q.back()]); } else ans = max(ans, sum[i]); } cout << ans << endl; return 0; }
标签:16px region none cli 前缀 最小值 图片 总结 event
原文地址:https://www.cnblogs.com/zZh-Brim/p/8954377.html