【HDOJ】【3415】Max Sum of Max-K-sub-sequence

DP/单调队列优化


  呃……环形链求最大k子段和。

  首先拆环为链求前缀和……

  然后单调队列吧<_<,裸题没啥好说的……

WA:为毛手写队列就会挂,必须用STL的deque?(写挂自己弱……sigh)

 1 //HDOJ 3415
 2 #include<queue>
 3 #include<cmath>
 4 #include<vector>
 5 #include<cstdio>
 6 #include<cstring>
 7 #include<cstdlib>
 8 #include<iostream>
 9 #include<algorithm>
10 #define rep(i,n) for(int i=0;i<n;++i)
11 #define F(i,j,n) for(int i=j;i<=n;++i)
12 #define D(i,j,n) for(int i=j;i>=n;--i)
13 #define pb push_back
14 #define CC(a,b) memset(a,b,sizeof(a))
15 using namespace std;
16 int getint(){
17     int v=0,sign=1; char ch=getchar();
18     while(!isdigit(ch)) {if(ch=='-') sign=-1; ch=getchar();}
19     while(isdigit(ch))  {v=v*10+ch-'0'; ch=getchar();}
20     return v*sign;
21 }
22 typedef long long LL;
23 const int N=100010,INF=~0u>>2;
24 const double eps=1e-8;
25 /*******************template********************/
26 
27 int a[N],f[N],q[N+N],s[N];
28 deque<int>Q;
29 void work(){
30     int n=getint(),k=getint();
31     s[0]=0;
32     F(i,1,n){
33         a[i]=getint();
34         s[i]=s[i-1]+a[i];
35     }
36     F(i,n+1,n+k-1) s[i]=s[i-1]+a[i-n];
37     int m=n+k-1;
38     
39     int _sum=-INF,pos=0,end=0;
40     Q.clear();
41     F(i,1,m){
42         while(!Q.empty() && s[Q.back()]>s[i-1]) Q.pop_back();
43         while(!Q.empty() && Q.front()<(i-k)) Q.pop_front();
44         Q.push_back(i-1);
45         if (s[i]-s[Q.front()]>_sum){
46             _sum=s[i]-s[Q.front()];
47             pos=Q.front()+1;
48             end=i;
49         }
50     }
51     printf("%d %d %d
",_sum,pos,(end>n) ? (end-n) : end);
52 }
53 int main(){
54     int T=getint();
55     while(T--) work();
56     return 0;
57 }
View Code
原文地址:https://www.cnblogs.com/Tunix/p/4320006.html