hdu 3415 Max Sum of Max-K-sub-sequence 单调队列dp
Max Sum of Max-K-sub-sequence
Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)Total Submission(s): 4581 Accepted Submission(s): 1656
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
单调队列优化dp的入门题
-----------------------
#include <iostream> #include <cstdio> #include <cstring> using namespace std; int a[411111]; int f[411111]; int que[1111111]; int pt[1111111]; int n,k; int T; int head,tail; int sum[411111]; int max_sum,start,end; int main() { scanf("%d",&T); while (T--) { memset(f,0,sizeof(f)); memset(que,0,sizeof(que)); memset(pt,0,sizeof(pt)); memset(sum,0,sizeof(sum)); scanf("%d%d",&n,&k); for (int i=1;i<=n;i++) { scanf("%d",&a[i]); a[i+n]=a[i]; } for (int i=1;i<=n+k;i++) { sum[i]+=sum[i-1]+a[i]; } //f[i]=max(sum[i]-sum[k]); head=tail=0; max_sum=start=end=-1e9; for (int i=1;i<=n+k;i++) { while ((head<tail)&&(i-pt[head]>k)) head++; while ((head<tail)&&(sum[i-1]<=que[tail-1])) tail--; que[tail]=sum[i-1],pt[tail++]=i-1; f[i]=sum[i]-que[head]; if (f[i]>max_sum) { max_sum=f[i]; start=pt[head]+1; end=i; } } if (start>n) start=start-n; if (end>n) end=end-n; printf("%d %d %d\n",max_sum,start,end); } return 0; }