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

来源:互联网 发布:linux dns配置 编辑:程序博客网 时间:2024/05/20 23:30

题意:给出一个有N个数字(-1000~1000,N<=10^5)的环状序列,让你求一个和最大的连续子序列,长度小于等于K。
对问题进行一下转化:令sum[i]=n[1]+n[2]+…+n[i];则该问题转化为:找最大的(sum[i]-sum[j])(i-j<=k),这需要从sum[i-1]~sum[i-k]中选择一个最小值作为j。所以,该问题又转化成了从一个区间中选择一个极值的问题。环状的解决方法还是很简单的,在序列后补上n[1]~n[k]即可正常计算。单调队列搞起。

#include <iostream>#include <cstring>#include <cstdio>#include <algorithm>using namespace std;int sum[200010];struct node{    int num,id;    node(){}    node(int _num, int _id)    {        id = _id;        num = _num;    }}q[200010];int main(){    int t;    scanf("%d",&t);    while(t--)    {        int n ,k , l , r , head , rear;        scanf("%d%d",&n,&k);        memset(sum,0,sizeof(sum));        memset(q,0,sizeof(q));        for(int i = 1 ; i <= n ; i++)        {            scanf("%d",&sum[i]);            sum[i]+=sum[i-1];        }        for(int i = n+1 ; i <= n+k ; i++)        {            sum[i] = sum[i-n] + sum[n] ;        }        head = rear  = 0;        int max0 = -0x7fffffff;        for(int i = 1 ; i <= n+k ; i++)        {            while(head < rear && q[rear-1].num >= sum[i-1]) rear--;            q[rear++] = node(sum[i-1],i-1);            while(head < rear && q[head].id < i-k) head++;            if(max0<sum[i] - q[head].num)            {                max0 = sum[i] - q[head].num;                l = q[head].id + 1;                r = i;            }        }        if(l>n) l = l - n;        if(r>n) r = r - n;        printf("%d %d %d\n",max0,l,r);    }    return 0;}
0 0
原创粉丝点击