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): 10831 Accepted Submission(s): 3970

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

问题链接HDU3415 Max Sum of Max-K-sub-sequence
问题简述:给定长度为n的循环序列,计算长度不超过k的子序列其和为最大。
问题分析:给代码不解释。
程序说明:(略)
参考链接:(略)
题记:(略)

AC的C++语言程序如下:

/* HDU3415 Max Sum of Max-K-sub-sequence */

#include <bits/stdc++.h>

using namespace std;

const int INF = 0x7F7F7F7F;
const int N = 100000;
int a[N * 2 + 1], q[N * 2 + 1];

int main()
{
    int t, n, k;
    scanf("%d", &t);
    while(t--) {
        scanf("%d%d", &n, &k);
        a[0] = 0;
        for(int i = 1; i <= n; i++) {
            scanf("%d", &a[i]);
            a[i] += a[i - 1];       // 计算前缀和
        }
        a[n + 1] = 0;
        for(int i = n + 1; i < n + k; i++)
            a[i] = a[n] + a[i - n];     // a[n + i] = a[i] + a[n],i=1...k

        int end = n + k - 1, head = 0, tail = 0, maxSum = -INF, l, r;
        for(int i = 1; i <= end ; i++) {
            while(head < tail && a[i - 1] < a[q[tail - 1]]) tail--;
            q[tail++] = i - 1;
            while(head < tail && i - q[head] > k) head++;
            if(maxSum < a[i] - a[q[head]]) {
                maxSum = a[i] - a[q[head]];
                l = q[head] + 1;
                r = i > n ? i % n : i;
            }
        }

        printf("%d %d %d\n", maxSum, l, r);
    }

    return 0;
}
发布了2289 篇原创文章 · 获赞 2373 · 访问量 265万+

猜你喜欢

转载自blog.csdn.net/tigerisland45/article/details/105440494