zoukankan      html  css  js  c++  java
  • hdu3415 Max Sum of Max-K-sub-sequence

     
     Max Sum of Max-K-sub-sequence
    Time Limit:1000MS     Memory Limit:32768KB     64bit IO Format:%I64d & %I64u
    Submit   Status

    Description

    Given a circle sequence A[1],A[2],A[3]......A[n]. Circle sequence means the left neighbour of A[1] is A[n] , and the right neighbour of A[n] is A[1].
    Now your job is to calculate the max sum of a Max-K-sub-sequence. Max-K-sub-sequence means a continuous non-empty sub-sequence which length not exceed K.
     

    Input

    The first line of the input contains an integer T(1<=T<=100) which means the number of test cases.  
    Then T lines follow, each line starts with two integers N , K(1<=N<=100000 , 1<=K<=N), then N integers followed(all the integers are between -1000 and 1000).
     

    Output

    For each test case, you should output a line contains three integers, the Max Sum in the sequence, the start position of the sub-sequence, the end position of the sub-sequence. If there are more than one result, output the minimum start position, if still more than one , output the minimum length of them.
     

    Sample Input

    4 6 3 6 -1 2 -6 5 -5 6 4 6 -1 2 -6 5 -5 6 3 -1 2 -6 5 -5 6 6 6 -1 -1 -1 -1 -1 -1
     

    Sample Output

    7 1 3 7 1 3 7 6 2 -1 1 1

     

    优先队列
    ,在1-n加一个n-1就可以把环转化成一条线,用sum求合,那么从i到j的和就可以用sum[j]-sum[i],这个技巧也可以优化求和!然后把sum[i]用优先队列,j从0到n+m;这样一个一个求和,就可以了!
    #include <iostream>
    #include<stdio.h>
    using namespace std;
    int num[250000],sum[250000],prim[250000];
    int main()
    {
        int n,m,t,i,front,rear;
        scanf("%d",&t);
        while(t--)
        {
            scanf("%d%d",&n,&m);
            sum[0]=0;
            for(i=1;i<=n;i++)
            {
                scanf("%d",&num[i]);
                sum[i]=sum[i-1]+num[i];//用合来简化运算
            }
            for(;i<=2*n;i++)
            {
               sum[i]=sum[i-1]+num[i-n];//大于N的部分i-n对应的相应的NUM
    
            }
            front=0;
            rear=0;
            int maxx=-1e10,sx=0,ex=0;
            for(i=1;i<=n+m;i++)
            {
                while(front<rear&&sum[prim[rear-1]]>sum[i-1])//插入
                {
                    rear--;
                }
    
                prim[rear++]=i-1;
                while(front<rear&&i-prim[front]>m)//去掉过界的
                {
                    front++;
                }
                if(maxx<sum[i]-sum[prim[front]])//保存最大值,和相应的坐标
                {
                    sx=prim[front]+1;
                    ex=i;
                    maxx=sum[i]-sum[prim[front]];
                }
    
            }
            if(sx>n)sx-=n;//注意大于n的其实是构造的模型,再重新
            if(ex>n)ex-=n;
            printf("%d %d %d
    ",maxx,sx,ex);
    
        }
        return 0;
    }
    

  • 相关阅读:
    Eclipse版本
    关于软件版本的说明
    JDK
    java2的三个版本
    vue 自定义下拉选择table组件
    网络图片转base64
    关于重力加速计文章
    整理 node-sass 安装失败的原因及解决办法
    kurentoClient
    es2020
  • 原文地址:https://www.cnblogs.com/jiangu66/p/3181738.html
Copyright © 2011-2022 走看看