hdu 3530 单调队列水题

2015-01-22 20:50:40 · 作者: · 浏览: 21


给你一个数列找到最长的子序列 中的最大值减最小值值m k之间



建立两个单调队列 一个递增 一个递减 当两个队首满足情况是就进行比较 找到最大值

当不满足是旧的移动队首 怎样移???

移动队首id较小的一个


#include
  
   
#include
   
     #include
     
     using namespace std
     ; int max
     (int a
     ,int b
     ) { return a
     >b
     ?a
     :b
     ; } int abs
     (int a
     ) { return a
     <0
     ?-a
     :a
     ; } int main() { int n
     ,m
     ,k
     ,i
     ,j
     ; int num
     [100010
     ]; int ma
     [100010
     ],mi
     [100010
     ]; int ida
     [100010
     ],idi
     [100010
     ]; while(~scanf
     ("%d%d%d"
     ,&n
     ,&m
     ,&k
     )) { for(i
     =1
     ;i
     <=n
     ;i
     ++) scanf
     ("%d"
     ,&num
     [i
     ]); int fax
     =0
     ,tax
     =0
     ; int fin
     =0
     ,tin
     =0
     ; int tt
     =0
     ; int now
     =0
     ; for(i
     =1
     ;i
     <=n
     ;i
     ++) { while(fax
     <tax
     &&ma
     [tax
     ]<=num
     [i
     ]) tax
     --; ma
     [++tax
     ]=num
     [i
     ]; ida
     [tax
     ]=i
     ; while(fin
     <tin
     &&mi
     [tin
     ]>=num
     [i
     ]) tin
     --; mi
     [++tin
     ]=num
     [i
     ]; idi
     [tin
     ]=i
     ; while(ma
     [fax
     +1
     ]-mi
     [fin
     +1
     ]>k
     &&fax
     <tax
     &&fin
     <tin
     ) { if(ida
     [fax
     +1
     ]<=idi
     [fin
     +1
     ]) { fax
     ++; now
     =ida
     [fax
     ]; } else { fin
     ++; now
     =idi
     [fin
     ]; } } if(ma
     [fax
     +1
     ]-mi
     [fin
     +1
     ]>=m
     ) tt
     =max
     (tt
     ,i
     -now
     ); } printf
     ("%d\n"
     ,tt
     ); } return 0
     ; }