HDU 3415 Max Sum of Max-K-sub-sequence(单调队列+最大连续子串和)
2017-08-14 15:22
465 查看
Max Sum of Max-K-sub-sequence
Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)Total Submission(s): 8433 Accepted Submission(s): 3095
Problem Description
Given a circle sequence A[1],A[2],A[3]......A
. Circle sequence means the left neighbour of A[1] is A
, and the right neighbour of A
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
<
ef42
br style="font-family:'Times New Roman';" />
Source
HDOJ Monthly Contest – 2010.06.05
题意:
队列组成的圆,求长度不大于k的连续子串最大和,输出和 左端点l 右端点r。
POINT:
首位相连只要在n后面在加k个数字就可以了。先搞一个sum数组来保存前缀和。
若以l作为左端点来找最大的答案:
ans[l]=max{sum[l+i-1]}-sum[l-1] (0<i<=k).
max{sum[l+i-1]} (0<i<=k) 这个部分可以用单调队列优化。
从1到n遍历左端点就可以了。
#include <iostream> #include <stdio.h> #include <string.h> #include <queue> using namespace std; const int N = 100100+4; const int INF=0x3f3f3f3f; struct node { int x,y; }a[N<<1]; int sum[N<<1]; int n,k; int ansmax,ansl,ansr; deque<int> q; void work() { for(int i=1;i<k;i++) { while(!q.empty()&&sum[i]>sum[q.back()]) q.pop_back(); q.push_back(i); } for(int i=1;i<=n;i++) { while(!q.empty()&&sum[i+k-1]>sum[q.back()]) q.pop_back(); while(!q.empty()&&q.front()<i) q.pop_front(); q.push_back(i+k-1); if(ansmax<sum[q.front()]-sum[i-1]) { ansmax=sum[q.front()]-sum[i-1]; ansr=q.front(); ansl=i; } } } int main() { int T; scanf("%d",&T); while(T--) { // init(); ansmax=-INF; scanf("%d %d",&n,&k); while(!q.empty()) q.pop_back(); for(int i=1;i<=n;i++) { scanf("%d",&a[i].x); a[i].y=i; sum[i]=sum[i-1]+a[i].x; } for(int i=n+1;i<=n+k;i++) { a[i]=a[i-n]; a[i].y=i; sum[i]=sum[i-1]+a[i].x; } work(); if(ansr>n) ansr-=n; printf("%d %d %d\n",ansmax,ansl,ansr); } }
相关文章推荐
- hdu 3415 Max Sum of Max-K-sub-sequence 单调队列 求连续l(1<=l<=k)个数的和的最大值 数列可循环
- HDU 3415 Max Sum of Max-K-sub-sequence(长度不超过k的最大连续子序列和,单调队列)
- 单调队列的一个应用——求解连续区间最大值(HDU Max Sum of Max-K-sub-sequence)
- HDU 3415(Max Sum of Max-K-sub-sequence-单调队列优化DP)
- [ACM] hdu 3415 Max Sum of Max-K-sub-sequence (单调队列)
- hdu 3415 Max Sum of Max-K-sub-sequence 单调队列dp
- HDU 3415 Max Sum of Max-K-sub-sequence(单调队列)
- HDU--杭电--3415--Max Sum of Max-K-sub-sequence--暴力或单调队列
- HDU--杭电--3415--Max Sum of Max-K-sub-sequence--暴力或单调队列
- hdu 3415 Max Sum of Max-K-sub-sequence(单调队列)
- HDU - 3415 Max Sum of Max-K-sub-sequence(单调队列)
- [HDU 3415] Max Sum of Max-K-sub-sequence · 单调队列
- HDU 3415 Max Sum of Max-K-sub-sequence 单调队列题解
- HDOJ 题目3415 Max Sum of Max-K-sub-sequence(单调队列求区间和最大值)
- HDU 3415-Max Sum of Max-K-sub-sequence 单调队列
- 【hdu3415】【单调队列 】Max Sum of Max-K-sub-sequence【求长度不大于k的区间最大子串和】
- hdu 3415 Max Sum of Max-K-sub-sequence(单调队列)
- HDU 3415 Max Sum of Max-K-sub-sequence(单调队列)
- HDU 3415 Max Sum of Max-K-sub-sequence(单调队列)
- HDU 3415 Max Sum of Max-K-sub-sequence[单调队列优化dp]