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

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

本题是需要单调队列的动态规划问题,求环上长度为K以内的且和最大的区间。

单调队列的队头维护的是满足在区间内部的且和最小的下标,这样才能得到最大和sum,因为和是sum[i] - sum[Q.front()]。使用双端队列实现单调队列单调性的维护。a的下标入队时依次弹出比a大的所有元素再将a的下标从队尾加入队列,以维持队列的单调性。

实现如下:

for(int i=1; i<=N; i++){
            while(!Q.empty() && sum[i -1] < sum[Q.back()])
                Q.pop_back();
            while(!Q.empty() && Q.front() < i - K)
                Q.pop_front();
            Q.push_back(i - 1);
        }

AC代码参考:

#include <queue>
#include <stdio.h>
#include <string.h>
#include <iostream>
#include <algorithm>

using namespace std;

const int INF = 0x3f3f3f3f;

int a[200010],sum[200010];
int main(){
//    freopen("in.txt","r",stdin);
    int cas;
    scanf("%d",&cas);
    while(cas--){
        int N,K;
        scanf("%d%d",&N,&K);
        sum[0] = 0;
        for(int i=1; i<=N; i++){
            scanf("%d",&a[i]);
            sum[i] = a[i] + sum[i - 1];
        }
        for(int i=N+1; i<N+K; i++)
            sum[i] = sum[i - 1] + a[i - N];
        int temp = N;
        N = N + K - 1;
        deque <int> Q;
        Q.clear();
        int ans = -INF,start,en;
        for(int i=1; i<=N; i++){
            while(!Q.empty() && sum[i - 1] < sum[Q.back()])
                Q.pop_back();
            while(!Q.empty() && Q.front() < i - K)
                Q.pop_front();
            Q.push_back(i - 1);
            if(sum[i] - sum[Q.front()] > ans){
                ans = sum[i] - sum[Q.front()];
                start = Q.front() + 1;
                en = i;
            }
        }
        if(en > temp)
            en %= temp;
        cout << ans << " " << start << " " << en << endl;
    }
    return 0;
}


 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值