Max Sum of Max-K-sub-sequence
Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)Total Submission(s): 5385 Accepted Submission(s): 1952
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.
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).
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题意:给出一个长度为n的环状序列,求序列中长度不超过k的和最大的连续子序列思路:环状序列看成长度为2*n的序列,然后求前缀和,求出max(sum[i] - sum[j])(i-k<j<i)。求这个最大值可以维护一个单调递增队列,队头元素始终为长度不超过k时最小的sum[i]的下标i。AC代码:#include <iostream> #include <cmath> #include <cstdlib> #include <cstring> #include <cstdio> #include <queue> #include <stack> #include <ctime> #include <vector> #include <algorithm> #define ll long long #define L(rt) (rt<<1) #define R(rt) (rt<<1|1) #define eps 1e-6; using namespace std; const int INF = 1e9; const int maxn = 100005; int n, k, head, tail, s, t; int num[maxn * 2], sum[maxn * 2]; int que[maxn * 2]; int main() { int tt; scanf("%d", &tt); while(tt--) { scanf("%d%d", &n, &k); sum[0] = 0; for(int i = 1; i <= n; i++) { scanf("%d", &num[i]); sum[i] = num[i] + sum[i - 1]; } for(int i = n + 1; i <= 2 * n; i++) sum[i] = num[i - n] + sum[i - 1]; int ans = -INF; head = tail = 0; que[tail++] = 0; for(int i = 1; i <= 2 * n; i++) { while(head < tail && que[head] < i - k) head++; if(ans < sum[i] - sum[que[head]]) { ans = sum[i] - sum[que[head]]; s = que[head] + 1, t = i; } while(head < tail && sum[que[tail - 1]] > sum[i]) tail--; que[tail++] = i; } if(s > n) s -= n; if(t > n) t -= n; printf("%d %d %d\n", ans, s, t); } return 0; }