hdu 3415

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

【题意】给出 一个k  和n个数 求 长度不超过k的 最大 连续子序列和 再输出起始和终止位置

【思路】 求连续的a[j]~a[i]的和最大 即求sum[i]-sum[j]最大 即对于每一个i 找一个最小的sum[j] 且i-j>k

           n最多有100000 个O( n^2)的复杂度绝对超时   所以要用优先队列优化

#include<iostream>
#include<cstdio>
#include<cstring>

using namespace std;

int a[200012],sum[200012],d[200002];//数组长度至少为n*2
int num[200002];

int main()
{
    int i,j,n,m,t,flag,p;
    scanf("%d",&t);
    while(t--)
    {
        scanf("%d%d",&n,&m);
        sum[0]=0;
        int maxxx=-100000;
        for(i=1;i<=n;i++)
        {
            scanf("%d",&a[i]);
            sum[i]=sum[i-1]+a[i];
        }
        for(;i<=n+m;i++)
            sum[i]=sum[i-1]+a[i-n];
        int front1,rear,start,end1;
        front1=rear=0;

        int ans=(-1)*10000000;
        for(i=1;i<=n+m;i++)
        {
            while(rear>front1&&(i-num[front1]>m))
                front1++;

            while(rear>front1&&sum[num[rear-1]]>sum[i-1])//  注意不是sum[i]
                rear--;

            num[rear++]=i-1;//注意不是i


            d[i]=sum[i]-sum[num[front1]];

            if(ans<d[i])
            {
                start=num[front1]+1;
                end1=i;
                ans=d[i];

            }

        }if(end1>n)
                    end1-=n;
            if(start>n)
                    start-=n;
        printf("%d %d %d\n",ans,start,end1);
    }
    return 0;
}

 

 

 

 

 

 

 

 

posted @ 2013-12-16 17:44  galaxy77  阅读(254)  评论(0编辑  收藏  举报