单调队列优化DP——最大子序列和

前言:

单调队列可以优化什么呢?我们发现单调队列是处理滑动窗口中的最值问题的。(一个固定长度的滑动窗口)。

输入一个长度为n的整数序列,从中找出一段长度不超过m的连续子序列,使得子序列中所有数的和最大。

注意: 子序列的长度至少是1。

输入格式
第一行输入两个整数n,m。

第二行输入n个数,代表长度为n的整数序列。

同一行数之间用空格隔开。

输出格式
输出一个整数,代表该序列的最大子序和。

数据范围
1≤n,m≤300000
输入样例:
6 4
1 -3 5 1 -2 3
输出样例:
7

#include
using namespace std;
const int N=3e5+7;
int s[N],a[N];
deque<int> q;
int main()
{
    int n,m; cin>>n>>m;
    for(int i=1;i<=n;i++){
        cin>>a[i];
        s[i]=s[i-1]+a[i];
    }
    int res=-0x3f3f3f3f;
    for(int i=1;i<=n;i++){
        while(q.size()&&q.front()<i-m) q.pop_front();//划出了区间则弹出
        res=max(res,s[i]-s[q.front()]);
        while(q.size()&&s[q.back()]>=s[i]) q.pop_back();//队尾位置大于当前值说明不需要
        q.push_back(i);
    }
    cout<<res<<endl;
}

你可能感兴趣的:(DP)