zoukankan      html  css  js  c++  java
  • HDU3415(单调队列)

    Max Sum of Max-K-sub-sequence

    Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)
    Total Submission(s): 7413    Accepted Submission(s): 2745


    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
     

    单调队列即保持队列中的元素单调递增(或递减)的这样一个队列,可以从两头删除,只能从队尾插入。单调队列的具体作用在于,由于保持队列中的元素满足单调性,对于上述问题中的每个j,可以用O(1)的时间找到对应的s[i]。(保持队列中的元素单调增的话,队首元素便是所要的元素了)。

    维护方法:对于每个j,我们插入s[j-1](为什么不是s[j]? 队列里面维护的是区间开始的下标,j是区间结束的下标),插入时从队尾插入。为了保证队列的单调性,我们从队尾开始删除元素,直到队尾元素比当前需要插入的元素优(本题中是值比待插入元素小,位置比待插入元素靠前,不过后面这一个条件可以不考虑),就将当前元素插入到队尾。之所以可以将之前的队列尾部元素全部删除,是因为它们已经不可能成为最优的元素了,因为当前要插入的元素位置比它们靠前,值比它们小。我们要找的,是满足(i>=j-k+1)的i中最小的s[i],位置越大越可能成为后面的j的最优s[i]。

    在插入元素后,从队首开始,将不符合限制条件(i>=j-k+1)的元素全部删除,此时队列一定不为空。(因为刚刚插入了一个一定符合条件的元素)

     1 //2016.8.22
     2 #include<iostream>
     3 #include<cstdio>
     4 #include<queue>
     5 
     6 using namespace std;
     7 
     8 const int N = 100005;
     9 const int inf = 0x3f3f3f3f;
    10 int arr[N], sum[N*2];
    11 
    12 int main()
    13 {
    14     int T, n, k, bg, ed;
    15     cin>>T;
    16     while(T--)
    17     {
    18         scanf("%d%d", &n, &k);
    19         sum[0] = 0;
    20         for(int i = 1; i <= n; i++)
    21         {
    22               scanf("%d", &arr[i]);
    23             sum[i] = sum[i-1]+arr[i];
    24         }
    25         for(int i = n+1; i < n+k; i++)
    26               sum[i] = sum[i-1]+arr[i-n];//求一个前缀和
    27         int ans = -inf;
    28         deque<int> dq;//双端队列
    29         for(int i = 1; i <= n+k-1; i++)
    30         {
    31             while(!dq.empty()&&sum[i-1]<sum[dq.back()])//保持单调,使队首的sum尽量小
    32                   dq.pop_back();
    33             while(!dq.empty()&&dq.front()<i-k)
    34                   dq.pop_front();
    35             dq.push_back(i-1);
    36             if(sum[i]-sum[dq.front()]>ans)//sum[i]-sum[dq.front()]就是子段的和
    37             {
    38                 ans = sum[i]-sum[dq.front()];
    39                 bg = dq.front()+1;
    40                 ed = i;
    41             }
    42         }
    43         if(ed>n)ed %= n;
    44         printf("%d %d %d
    ", ans, bg, ed);
    45     }
    46 
    47     return 0;
    48 }
  • 相关阅读:
    WCF 第四章 绑定 在多个绑定上暴露一个服务契约
    WCF 第五章 行为 事务跨操作事务流
    WCF 第五章 导出并发布元数据(服务行为)
    WCF 第五章 行为 通过配置文件暴露一个服务行为
    WCF 第五章 不支持会话的绑定的默认并发和实例
    WCF 第五章 并发和实例(服务行为)
    WCF 第五章 行为 总结
    WCF 第四章 绑定 绑定元素
    WCF 第五章 行为 事务之选择一个事务协议OleTx 或者WSAT
    WCF 第四章 绑定 比较各种绑定的性能和可扩展性
  • 原文地址:https://www.cnblogs.com/Penn000/p/5795763.html
Copyright © 2011-2022 走看看