DP/单调队列优化
题解:http://www.cnblogs.com/yymore/archive/2011/06/22/2087553.html
引用:
首先我们要明确几件事情
1.假设我们现在知道序列(i,j)是符合标准的,那么如果第j+1个元素不比(i,j)最大值大也不比最小值小,那么(i,j+1)也是合法的
2.如果(i,j)不合法的原因是差值比要求小,那在(i,j)范围内的改动是无效的,需要加入j+1元素充当最大值或者最小值才可能获得合法的序列
3.假设序列(i,j)的差值比要求大,那么我们必须将其中的最大值或者最小值从序列中删除出去,才可能获得一个合法的序列,只往里加入元素是不可能令序列合法的
1 //HDOJ 3530 2 #include<cmath> 3 #include<queue> 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 const int N=1e6+10,INF=~0u>>2; 23 const double eps=1e-8; 24 /*******************template********************/ 25 26 deque<int>mx,mn; 27 int a[N]; 28 int main(){ 29 #ifndef ONLINE_JUDGE 30 freopen("input.txt","r",stdin); 31 // freopen("output.txt","w",stdout); 32 #endif 33 int n,m,k; 34 while(scanf("%d%d%d",&n,&m,&k)!=EOF){ 35 int start=0,ans=0; 36 F(i,1,n) a[i]=getint(); 37 mx.clear(); mn.clear(); 38 F(i,1,n){ 39 while(!mx.empty() && a[mx.back()]<=a[i]) mx.pop_back(); 40 while(!mn.empty() && a[mn.back()]>=a[i]) mn.pop_back(); 41 mx.pb(i); mn.pb(i); 42 while(a[mx.front()]-a[mn.front()]>k){ 43 if (mx.front()<mn.front()){ 44 start=mx.front(); 45 mx.pop_front(); 46 }else{ 47 start=mn.front(); 48 mn.pop_front(); 49 } 50 } 51 if (a[mx.front()]-a[mn.front()]>=m) 52 ans=max(i-start,ans); 53 } 54 printf("%d ",ans); 55 } 56 return 0; 57 }