题意:给一串数,求解最大连续子序列和。
思路:和HDU1003一样,增加了两个条件,所取的区间长度必须在K范围内,另外这是一个循环数组,所以考虑可以用单调队列来做,另外可以直接循环数组操作,和1003差不多。
#include <iostream>
#include <stdio.h>
#include <cstring>
#define N 200050
using namespace std;
int S[N],q[N];
int MAX,T,n,K,flag;
int first,last;
int H,L;
void solve()
{
for(int i=n+1; i<n+K; i++)
S[i]=S[n]+S[i-n];
n+=K;
H=L=0;
MAX=last=1;
MAX=-1001;
for(int i=1; i<n; i++)
{
while(L<H&&S[i-1]<S[q[H-1]-1])
H--;
q[H++]=i;
while(L<H&&i-q[L]+1>K)
L++;
if(S[i]-S[q[L]-1]>MAX)
{
MAX=S[i]-S[q[L]-1];
first=q[L];
last=i;
}
}
last=(last-1)%flag+1;
first=(first-1)%flag+1;
}
int main()
{
scanf("%d",&T);
while(T--)
{
scanf("%d%d",&n,&K);
flag=n;
for(int i=1; i<=n; i++)
{
scanf("%d",&S[i]);
S[i]+=S[i-1];
}
solve();
printf("%d %d %d\n",MAX,first,last);
}
return 0;
}
另外贴上1003的代码:
#include <iostream>
#include <stdio.h>
using namespace std;
int a[100001],b[100001];
int main()
{
int i,k=1,t,n;
cin>>t;
while(t--)
{
cin>>n;
for(i=1;i<=n;i++)
cin>>a[i];
b[1]=a[1];
for(i=2;i<=n;i++)
if(b[i-1]<0) b[i]=a[i];
else b[i]=a[i]+b[i-1];
int Max=b[1],p=0,start,End=1;
for(i=1;i<=n;i++)
if(b[i]>Max) {Max=b[i]; End=i;}
start=End;
for(i=End;i>=1;i--)
{
p+=a[i];
if(p==Max) start=i;
else continue;
}
printf("Case %d:\n%d %d %d\n",k++,Max,start,End);
if(t) cout<<endl;
}
return 0;
}