zoukankan      html  css  js  c++  java
  • HDU 3415 Max Sum of MaxKsubsequence

    HDU_3415

        由于原序列是一个环,为了方便处理可以在序列尾补K-1个元素,从而变成了链。设前i项和为A[i],f[i]为右边界在第i项上时的最大和,则f[i]=max{A[i]-A[j]}(i-K<=j<i),于是我们可以用一个单调队列来维护至今遇到的最小的A[j]即可,且i-K<=j<i。

        由于要求序列非空(或者说要求j<i),所以插入操作要放到最后去做,同时一开始要向队列里插入一个标号为0且值为0的元素。

    #include<stdio.h>
    #include<string.h>
    #define MAXD 200010
    #define INF 1000000000
    int N, K, f[MAXD], x[MAXD], A[MAXD], q[MAXD], d[MAXD];
    void init()
    {
    int i, j;
    scanf("%d%d", &N, &K);
    for(i = 1; i <= N; i ++)
    scanf("%d", &x[i]);
    A[0] = 0;
    for(i = 1; i <= N; i ++)
    {
    A[i] = x[i];
    A[i] += A[i - 1];
    }
    for(i = N + 1; i < N + K; i ++)
    {
    A[i] = x[i - N];
    A[i] += A[i - 1];
    }
    }
    void solve()
    {
    int i, j, front, rear, a, b, max, sum;
    front = rear = 0;
    max = - INF;
    d[rear] = 0;
    q[rear] = 0;
    rear ++;
    for(i = 1; i < N + K; i ++)
    {
    while(front < rear && d[front] < i - K)
    front ++;
    sum = A[i] - A[d[front]];
    if(sum > max)
    {
    max = sum;
    a = d[front];
    b = i;
    }
    while(front < rear && q[rear - 1] > A[i])
    rear --;
    q[rear] = A[i];
    d[rear] = i;
    rear ++;
    }
    if(b > N)
    b -= N;
    printf("%d %d %d\n", max, a + 1, b);
    }
    int main()
    {
    int t;
    scanf("%d", &t);
    while(t --)
    {
    init();
    solve();
    }
    return 0;
    }


  • 相关阅读:
    详解vue生命周期
    浅谈前端中的mvvm与mvc
    实际项目开发需要注意的tips
    toFixed()一不小心踩了一个坑
    git学习(持续踩坑中🤣)
    webpack基础
    创建git仓库并发布
    注册npm账号
    Invalid left-hand side in assignment
    关于项目中js原型的使用
  • 原文地址:https://www.cnblogs.com/staginner/p/2245088.html
Copyright © 2011-2022 走看看