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

其实这是第一个单调队列的题目吧!!之前看了这个知识点的资料不是很懂,可见这个题目做的纠结,后面是参考了讨论区,才AC后面也不是很懂吧,看了很久。。

       序列是环状的,所以可以在序列后面复制一段(或者复制前k个数字)。如果用sum[i]来表示复制过后的序列的前i个数的和,那么任意一个子序列[i..j]的和就等于[j]-s[i-1]。对于每一个j,用s[j]减去最小的一个s[i](i>=j-k+1)就可以得到以j为终点长度不大于k的和最大的序列了。将原问题转化为这样一个问题后,就可以用单调队列解决了。

       找到前面的第i-K+1个,在后面K个里面找最大值,相减就行啦!!!找的时候就需要单调队列,不然会超时吧!!!!

代码:

#include<iostream>
#include<cstdio>
#include<cstring>
#include<queue>
using namespace std;
const int n = 100008;
const int mm = 1e9;
int sum[n<<1];
struct node{
    int x,y;
}q[n<<1];

int main()
{
    int i,j,maxx,t,w,e;
    int N,K,f,r;
    scanf("%d",&t);
    while(t--){
        memset(sum,0,sizeof(sum));
        memset(q,0,sizeof(q));
        scanf("%d%d",&N,&K);
        for(i=1;i<=N;i++){
            scanf("%d",&sum[i]);
            sum[i]+=sum[i-1];
        }
        for(;i<=N+K;i++){
            sum[i]=sum[N]+sum[i-N];
        }

        maxx=-mm;
        w=e=0;

        for(i=1;i<=N+K;i++){
            while( w < e && q[e-1].x < sum[i]) e--;
            q[e].x=sum[i];
            q[e++].y=i;
            while( w < e && i - q[w].y >= K ) w++;

            if(i >= K && q[w].x-sum[i-K] > maxx){
                maxx=q[w].x-sum[i-K];
                f=i-K+1;
                r=q[w].y;
            }

        }
        printf("%d %d %d\n",maxx,f,(r > N?r-N:r));
    }
    return 0;
}

继续.......

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值