HDU 3415——Max Sum of Max-K-sub-sequence

Problem Description
Given a circle sequence A[1],A[2],A[3]......A[n]. Circle sequence means the left neighbour of A[1] is A[n] , and the right neighbour of A[n] is A[1].
Now your job is to calculate the max sum of a Max-K-sub-sequence. Max-K-sub-sequence means a continuous non-empty sub-sequence which length not exceed K.
 


 

Input
The first line of the input contains an integer T(1<=T<=100) which means the number of test cases.  
Then T lines follow, each line starts with two integers N , K(1<=N<=100000 , 1<=K<=N), then N integers followed(all the integers are between -1000 and 1000).
 


 

Output
For each test case, you should output a line contains three integers, the Max Sum in the sequence, the start position of the sub-sequence, the end position of the sub-sequence. If there are more than one result, output the minimum start position, if still more than one , output the minimum length of them.
 


 

Sample Input
  
  
4 6 3 6 -1 2 -6 5 -5 6 4 6 -1 2 -6 5 -5 6 3 -1 2 -6 5 -5 6 6 6 -1 -1 -1 -1 -1 -1
 


 

Sample Output
  
  
7 1 3 7 1 3 7 6 2 -1 1 1
 


 

Author
shǎ崽@HDU
 


 

Source
 


 

Recommend
lcy


 

【算法分析】

 

和 1003 Max Sum 差不多,不同之处有两点;

1、数组是循环的

2、限制了最长的连续字段的长度为 K

还是最原始的想法:找最大的 s[i] - s[j] 只不过 i - K <= j < i 了

那么还是可以用单调队列优化,为什么?

区间:[i - K , i] 是单调的

接着的东西就跟 1003 差不多了

PS:由于数组定义小了,硬是WA了将近一个小时!以后一定要注意数据的大小!!!

下面的代码仅供参考:

 

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#define INF 0x7fffffff
using namespace std;
int main()
{
    int T,N,K,st,en,Max;
    int a[200005],q[200005],head,tail;
    scanf("%d",&T);
    while(T--)
    {
        scanf("%d%d",&N,&K);
        a[0]=0;
        for(int i=1;i<=N;i++)
        {
            scanf("%d",&a[i]);
            a[i]+=a[i-1];
        }
        for(int i=1;i<=K;i++)
            a[N+i]=a[N]+a[i];
        head=tail=0;
        q[++tail]=0;
        Max=-INF;
        for(int i=1;i<=N+K;i++)
        {
            while(head<tail && q[head+1]<i-K) head++;
            if(a[i]-a[q[head+1]]>Max)
            {
                Max=a[i]-a[q[head+1]];
                st=q[head+1]+1;
                en=i;
            }
            while(head<tail && a[q[tail]]>a[i]) tail--;
            q[++tail]=i;

        }
        st=(st-1)%N+1;
        en=(en-1)%N+1;
        printf("%d %d %d\n",Max,st,en);
    }
    return 0;
}


 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值