[单调队列] hdu 3415 Max Sum of Max-K-sub-sequence

题意:

给n和k,再给你n个形成环的数

问你连续不超过k个数的最大和是多少

并输出区间,和一样以左端点最小。再一样以长度最小

思路:

我们记录前缀和sum[i]

开一个单调队列维护sum[i-1]的值最小

由于对于到当前位置的和为sum[i]-sum[j] 假设sum[j]越小,那么sum[i]就越大

所以里面维护的就是到当前位置符合要求最小的sun[j]

代码:

#include"cstdlib"
#include"cstdio"
#include"cstring"
#include"cmath"
#include"queue"
#include"algorithm"
#include"iostream"
#include"map"
using namespace std;
#define N 222222
int sum[N],v[N];
int q[2*N];
int main()
{
    int t;
    cin>>t;
    while(t--)
    {
        int n,k;
        scanf("%d%d",&n,&k);
        //deque<int>q;
        sum[0]=0;
        for(int i=1;i<=n;i++)
        {
            scanf("%d",&v[i]);
            sum[i]=sum[i-1]+v[i];
        }
        for(int i=n+1;i<2*n;i++) sum[i]=sum[i-1]+v[i-n];
        int ans=-999999999,x,y;
        int top=0,ed=0;

        for(int i=1;i<2*n;i++)
        {
            while(top<ed && sum[q[ed-1]]>=sum[i-1]) ed--;
            q[ed++]=i-1;
            while(top<ed && i-q[top]>k) top++;
            int tep=sum[i]-sum[q[top]];
            if(tep>ans)
            {
                ans=tep;
                x=q[top]+1;
                y=i;
            }
        }
        if(y>n) y-=n;
        printf("%d %d %d
",ans,x,y);
    }
    return 0;
}


原文地址:https://www.cnblogs.com/zsychanpin/p/7239221.html