hdu3415 Max Sum of Max-K-sub-sequence 单调队列

//hdu3415 Max Sum of Max-K-sub-sequence
//单调队列
//首先想到了预处理出前缀和利用s[i] - s[j]表示(j,i]段的和
//之后的问题就转换成了求一个最小的s[j]了,这样就能够单调队列
//求最小值。

//队列中维护的是区间的開始的位置j。我们插入队列中的是j-1,由于
//这个时候s[i] - s[j-1]刚好就是[j,i]段闭区间的和

//这里用两种方式实现,一种是stl,一种是手动模拟,两者的速度,測试的
//结果在杭电測试都是一样的,499ms。
//
//单调队列的路还长着,继续走吧

#include <cstdio>
#include <queue>
#include <algorithm>
#include <iostream>
#include <cstring>
using namespace std;
typedef long long ll;
const int maxn = 1e5 + 8;
ll a[maxn*2];
ll sum[maxn*2];
ll x[maxn * 2];
int deq[maxn * 2];
int n,k;
int mod;
void input(){
    scanf("%d%d",&n,&k);
    for (int i=1;i<=n;i++){
        scanf("%lld",&a[i]);
    }
    for (int i=n+1;i<=2*n;i++){
        a[i] = a[i-n];
    }

    sum[0] = 0;

    for (int i=1;i<=n;i++){
        sum[i] = sum[i-1] + a[i];
    }

    for (int i=1;i<k;i++){
        sum[i+n]= sum[i+n-1] + a[i];
    }
    mod = n;
    n = n + k - 1;

}

void solve(){
    int s,e;
    int head = 0,tail = 0;
    ll mx = -1e10;
    for (int i=1;i<=n;i++){
        while(tail > head && sum[i-1]<=sum[deq[tail-1]])
            tail--;
        while(tail > head && deq[head]<i-k)
            head++;
        deq[tail++] = i-1;
        if (sum[i] - sum[deq[head]] > mx){
            mx = sum[i] - sum[deq[head]];
            s = deq[head] + 1;
            e = i;
        }
    }

    if (e > mod)
        e -= mod;
    printf("%lld %d %d\n",mx,s,e);

    //printf("%lld %d\n",x[mk],(mk+k)%n);
}

//void solve(){
//    int s,e;
//    deque<int> deq;
//    deq.clear();
//    ll mx = -1e10;
//    for (int i=1;i<=n;i++){
//        while(!deq.empty() && sum[i-1]<=sum[deq.back()])
//            deq.pop_back();
//        while(!deq.empty() && deq.front()<i-k)
//            deq.pop_front();
//        deq.push_back(i-1);
//        if (sum[i] - sum[deq.front()]>mx){
//            mx = sum[i] - sum[deq.front()];
//            s = deq.front() + 1;
//            e = i;
//        }
//    }
//
//    if (e > mod)
//        e -= mod;
//    printf("%lld %d %d\n",mx,s,e);
//
//    //printf("%lld %d\n",x[mk],(mk+k)%n);
//}

int main(){
    //freopen("1.txt","r",stdin);
    int t;
    scanf("%d",&t);
    while(t--){
        input();
        solve();
    }
    return 0;
}
时间: 2024-10-08 14:57:46

hdu3415 Max Sum of Max-K-sub-sequence 单调队列的相关文章

$Poj3017\ Cut\ The\ Sequence$ 单调队列优化$DP$

Poj   AcWing Description 给定一个长度为N的序列 A,要求把该序列分成若干段,在满足“每段中所有数的和”不超过M的前提下,让“每段中所有数的最大值”之和最小. N<=105,M<=1011,0<Ai<=106 Sol 一篇比较清楚的题解 $OvO$ $F[i]$表示把前$i$个数分成若干段,满足每段中所有数之和不超过$M$的前提下,各段的最大值之和的最小值 不难推出转移方程: 但是直接枚举$j$的做法是$O(N^{2})$的,显然过不去,还要优化. DP转移

POJ 3709 K-Anonymous Sequence (单调队列优化)

题意:给定一个不下降数列,一个K,将数列分成若干段,每段的数字个数不小于K,每段的代价是这段内每个数字减去这段中最小数字之和.求一种分法使得总代价最小? 思路:F[i]表示到i的最小代价.f[i]=min(f[j]+sum[i]-sum[j]-(i-j)*a[j+1]);(i-j>=K) 对于j1,j2,j1<j2且j2更优得 f[j1]+sum[i]-sum[j1]-(i-j1)*a[j1+1]>f[j2]+sum[i]-sum[j2]-(i-j2)*a[j2+1] 得到: f[j1]

hdu3415——Max Sum of Max-K-sub-sequence

Max Sum of Max-K-sub-sequence Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total Submission(s): 6130    Accepted Submission(s): 2234 Problem Description Given a circle sequence A[1],A[2],A[3]......A[n]. Circle s

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

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

K - Max Sum Plus Plus

K - Max Sum Plus Plus Time Limit:1000MS     Memory Limit:32768KB     64bit IO Format:%I64d & %I64u Description Now I think you have got an AC in Ignatius.L's "Max Sum" problem. To be a brave ACMer, we always challenge ourselves to more diffi

Leetcode: Max Sum of Rectangle No Larger Than K

Given a non-empty 2D matrix matrix and an integer k, find the max sum of a rectangle in the matrix such that its sum is no larger than k. Example: Given matrix = [ [1, 0, 1], [0, -2, 3] ] k = 2 The answer is 2. Because the sum of rectangle [[0, 1], [

【leetcode】363. Max Sum of Rectangle No Larger Than K

题目描述: Given a non-empty 2D matrix matrix and an integer k, find the max sum of a rectangle in the matrix such that its sum is no larger than k. 解题思路: 根据题意,寻找二维数组中所有可以组成的矩形中面积不超过k的最大值,所以必须要求出可能组成的矩形的面积并与k比较求出最终结果.这里为了最终不超时,可以在一下方面进行优化: 1.设置一个数组比较当前列(或