zoukankan      html  css  js  c++  java
  • HDOJ 3415 Max Sum of Max-K-sub-sequence(单调队列)

    因为是circle sequence,可以在序列最后+序列前n项(或前k项);利用前缀和思想,预处理出前i个数的和为sum[i],则i~j的和就为sum[j]-sum[i-1],对于每个j,取最小的sum[i-1],这就转成一道单调队列了,维护k个数的最小值。

    ----------------------------------------------------------------------------------

    #include<cstdio>
    #include<deque>
    #define rep(i,n) for(int i=0;i<n;i++)
    #define Rep(i,l,r) for(int i=l;i<=r;i++)
    using namespace std;
    const int maxn=100000*2+5;
    const int inf=1<<30;
    int sum[maxn];
    deque<int> q;
    deque<int> num;
    int main()
    {
    freopen("test.in","r",stdin);
    freopen("test.out","w",stdout);
    int kase;
    scanf("%d",&kase);
    while(kase--) {
    sum[0]=0;
    int n,k,t;
    scanf("%d%d",&n,&k);
    Rep(i,1,n) {
    scanf("%d",&t);
    sum[i]=sum[i-1]+t;
    }
    Rep(i,1,n) sum[i+n]=sum[n]+sum[i];
    while(!q.empty()) { q.pop_back(); num.pop_back(); }
    int ans[3]={-inf,0,0};
    rep(i,n+n) {
    if(i && sum[i]-q.front()>ans[0]) {
    ans[0]=sum[i]-q.front();
    ans[1]=num.front()+1; ans[2]=i;
    }
    if(!q.empty()) {
    if(num.front()+k<i+1) { q.pop_front(); num.pop_front(); }
    while(!q.empty() && q.back()>=sum[i]) { 
       q.pop_back();
    num.pop_back(); 
    }
    }
    q.push_back(sum[i]);
    num.push_back(i);
    }
    if(ans[2]>n) ans[2]%=n;
    printf("%d %d %d ",ans[0],ans[1],ans[2]);
    }
    return 0;
    }

    ----------------------------------------------------------------------------------

    Max Sum of Max-K-sub-sequenceTime Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)
    Total Submission(s): 6213    Accepted Submission(s): 2270


    Problem 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
     

    Author
    shǎ崽@HDU
     

    Source
     

    Recommend
    lcy   |   We have carefully selected several similar problems for you:  3423 3417 3418 3419 3421 

  • 相关阅读:
    绘图QPainter-画刷
    绘图QPainter-画笔
    pyqt5-多线程QThread类
    升级时出现错误的解决办法
    打包pyinstaller
    多文档界面QMdiArea
    停靠窗口QDockWidget
    堆叠窗口QStackedWidget
    VC运行库版本不同导致链接.LIB静态库时发生重复定义问题的一个案例分析和总结
    【一】ODB
  • 原文地址:https://www.cnblogs.com/JSZX11556/p/4355709.html
Copyright © 2011-2022 走看看