[单调队列] 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\n",ans,x,y);
}
return 0;
}
浙公网安备 33010602011771号