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

 

链接:http://acm.hdu.edu.cn/showproblem.php?pid=3415

题意:一个共有N个整数的环形串,计算最多有K个整数的连续子串的和。

分析:单调队列。用sum[i]存储前i个整数的和,则i+1到j之间的整数和就是:sum[j]-sum[i]。对于环形情况的处理,只要在整数串最后补上前K个数就可以对其进行线性串的处理。单调队列的队首存放当前K+1个SUM值的最小值。

 

Source Code:

#include<stdio.h>
#define maxn 100010
#define INF 0x3f3f3f3f

struct node{
    int val,idx;
}que[maxn<<1];
int sum[maxn<<1],num[maxn];

int main()
{
    int i,n,k,T,head,tail,max,l,r;
    sum[0]=0;
    scanf("%d",&T);
    while(T--){
        scanf("%d %d",&n,&k);
        for(i=1;i<=n;i++){
            scanf("%d",&num[i]);
            sum[i]=sum[i-1]+num[i];
        }
        for(i=1;i<=k;i++)
            sum[i+n]=sum[i+n-1]+num[i];
        head=tail=0;
        max=-INF;
        for(i=0;i<n+k;i++){
            while(head<tail&&que[tail-1].val>sum[i]) tail--;
            que[tail].val=sum[i];que[tail++].idx=i;
            while(head<tail&&que[head].idx<=i-k) head++;
            if(max<(sum[i+1]-sum[que[head].idx])){
                max=sum[i+1]-sum[que[head].idx];
                l=que[head].idx+1;
                r=i+1;
            }
        }
        if(r>n) r-=n;
        printf("%d %d %d\n",max,l,r);
    }
    return 0;
}

 

(这题几次把我搞到崩溃,觉得代码写的确实没有问题,可提交之后一直WA...最后更换了点思路才AC了。唉,还是对单调队列没有完全理解吧。)

你可能感兴趣的:(HDU 3415 Max Sum of Max-K-sub-sequence)