[单调队列] hdu 3415 Max Sum of Max-K-sub-sequence

题意:

给n和k,再给你n个形成环的数

问你连续不超过k个数的最大和是多少

并输出区间,和一样以左端点最小,再一样以长度最小

思路:

我们记录前缀和sum[i]

开一个单调队列维护sum[i-1]的值最小

因为对于到当前位置的和为sum[i]-sum[j] 如果sum[j]越小,那么sum[i]就越大

所以里面维护的就是到当前位置符合要求最小的sun[j]

代码:

#include"cstdlib"
#include"cstdio"
#include"cstring"
#include"cmath"
#include"queue"
#include"algorithm"
#include"iostream"
#include"map"
using namespace std;
#define N 222222
int sum[N],v[N];
int q[2*N];
int main()
{
    int t;
    cin>>t;
    while(t--)
    {
        int n,k;
        scanf("%d%d",&n,&k);
        //deque<int>q;
        sum[0]=0;
        for(int i=1;i<=n;i++)
        {
            scanf("%d",&v[i]);
            sum[i]=sum[i-1]+v[i];
        }
        for(int i=n+1;i<2*n;i++) sum[i]=sum[i-1]+v[i-n];
        int ans=-999999999,x,y;
        int top=0,ed=0;

        for(int i=1;i<2*n;i++)
        {
            while(top<ed && sum[q[ed-1]]>=sum[i-1]) ed--;
            q[ed++]=i-1;
            while(top<ed && i-q[top]>k) top++;
            int tep=sum[i]-sum[q[top]];
            if(tep>ans)
            {
                ans=tep;
                x=q[top]+1;
                y=i;
            }
        }
        if(y>n) y-=n;
        printf("%d %d %d\n",ans,x,y);
    }
    return 0;
}

版权声明:本文为博主原创文章,未经博主允许不得转载。

时间: 2024-10-14 05:15:59

[单调队列] hdu 3415 Max Sum of Max-K-sub-sequence的相关文章

[多校2015.01.1002 单调队列] hdu 5289 Assignment

题意: 给你n个人和一个k 问你把这n个人分成多少个连续的子区间,要求区间每个数两两相差绝对值小于k 思路: 我们仅仅只需要对于当前位置,最左边那个和它绝对值相差大于等于k 的位置在哪 假设对于i这个位置,最左边的位置是tep,不存在的话tep=0 那么当且位置的贡献就是 sum[i]=min(i-tep,sum[i-1]+1); 那么对于这个位置怎么求的话,我是使用了两个单调队列 第一次维护递增的,第二次维护递减的. 每次先把不满足的点全部出队,然后记录最大的下标 然后入队 代码: #incl

HDU 1003 Max Sum(dp,最大连续子序列和)

Max Sum Problem Description Given a sequence a[1],a[2],a[3]......a[n], your job is to calculate the max sum of a sub-sequence. For example, given (6,-1,5,4,-7), the max sum in this sequence is 6 + (-1) + 5 + 4 = 14. Input The first line of the input

HDU 1003.Max Sum【最大连续子序列和】【8月14】

Max Sum Problem Description Given a sequence a[1],a[2],a[3]......a[n], your job is to calculate the max sum of a sub-sequence. For example, given (6,-1,5,4,-7), the max sum in this sequence is 6 + (-1) + 5 + 4 = 14. Input The first line of the input

HDU 3401 Trade dp 单调队列优化

戳这里:3401 题意:给出第 i 天的股票买卖价格(APi,BPi),以及每天股票买卖的数量上限(ASi,BSi),要求任两次交易需要间隔 W 天以上,即第 i 天交易,第 i + W + 1 天才能再交易,求最多能赚多少钱 思路:dp[i][j] = max(dp[i - 1][j], max(dp[f][k] - (j - k) * APi[i]), max(dp[f][k] + (k - j) * BPi[i])); 从式子中观察出,若两天都持有股票数 j 时,之后的那一天所赚的钱不小于

【HDU 1081】To The Max(求子矩阵元素和)

题目应该很容易看懂,是为了求一个矩阵之内最大的一个子矩阵的和. 子矩阵的和表示的是该矩阵内所有元素的和. 方法引入: 首先当然十分容易的可以想到一维求子段的和. 假设数组为a[110]; int sum = 0, MAX = 0,n; for (int i = 0; i < n; i++) { if (sum < 0) sum = 0; sum += a[i]; if (sum>MAX) MAX = sum; } 其中a[i]表示的是你所要积的范围大小,因为是一维,所以我们要积的是每一个

POJ 1003 Max Sum

Max Sum Problem Description Given a sequence a[1],a[2],a[3]......a[n], your job is to calculate the max sum of a sub-sequence. For example, given (6,-1,5,4,-7), the max sum in this sequence is 6 + (-1) + 5 + 4 = 14. Input The first line of the input

背包问题入门(单调队列优化多重背包

背包问题 写这篇文章主要是为了帮帮新人吧,dalao勿喷.qwq 一般的背包问题问法 每种物品都有一个价值w和体积c.//这个就是下面的变量名,请看清再往下看. 你现在有一个背包容积为V,你想用一些物品装背包使得物品总价值最大. 01背包 多种物品,每种物品只有一个.求能获得的最大总价值. 我们考虑是否选择第i件物品时,是需要考虑前i-1件物品对答案的贡献的. 分析 如果我们不选择第i件物品,那我们就相当于是用i-1件物品,填充了体积为v的背包所得到的最优解. 而我们选择第i件物品的时候,我们要

HDU 3415 Max Sum of Max-K-sub-sequence 单调队列题解

本题又是一题单调队列题解. 技巧就是需要计算好前n项和Sn = a1 + a2 + ... an 这样方便处理. 记录一条单调队列,其意义是: q(head), q(head+1), ...q(tail) 其中头q(head)代表当前最佳解的起点 这样我们只需要在求某点为结尾的S[i] - S[q(head)就得到当前最佳值. 了解了单调数列,知道其中的记录意义,那么这道题就没有难度了.我也是了解这些信息之后就自己敲出代码的. 不过有些细节没写好也让我WA了几次. 最近少刷水题,而一直都是每天一

hdu 3415 Max Sum of Max-K-sub-sequence(单调队列)

题目链接:hdu 3415 Max Sum of Max-K-sub-sequence 题意: 给你一串形成环的数,让你找一段长度不大于k的子段使得和最大. 题解: 我们先把头和尾拼起来,令前i个数的和为sum[i]. 然后问题变成了求一个max{sum[i]-sum[j]}(i-k<j<i) 意思就是对于每一个sum[i],我们只需要找一个满足条件的最小的sum[j],然后我们就可以用一个单调队列来维护. 1 #include<bits/stdc++.h> 2 #define F