HDU 3530

单调队列DP,开始想错了,WA了好多次。

后来才发现错在哪了。。

我们先枚举子串的结尾,并维护2个队列(单增,单减)。

如果2个队列的队头的差别大于k,则较小的队头值的位置肯定不满足要求。

那么就通过减小大的,增大小的来是dif更小。

直到找到一个合法位置now,那么对于i-1这个子串的结尾,now到i-1这个区间肯定满足要求。

所以有ans = max(ans,i-1-now+1)。

now初始值为-1,因为有可能最大长度为n。

View Code
 1 #include<iostream>

 2 #include<cstdio>

 3 #include<cmath>

 4 #define MAXN 100005

 5 using namespace std;

 6 int data[MAXN];

 7 

 8 int main()

 9 {

10     int n,m,k;

11     while (scanf("%d%d%d",&n,&m,&k) != EOF) {

12         for (int i(0); i<n; ++i) {

13             scanf("%d",&data[i]);

14         }

15         int min_que[MAXN],max_que[MAXN];

16         int min_front(-1),min_back(-1),max_front(-1),max_back(-1);

17         int ans = 0, now(-1);

18         for (int i(0); i<n; ++i) {

19             while (max_front != max_back && data[max_que[max_back]] <= data[i])--max_back;

20             while (min_front != min_back && data[min_que[min_back]] >= data[i])--min_back;

21             min_que[++min_back] = max_que[++max_back] = i;

22             while (min_front != min_back && max_front != max_back && 

23                    abs(data[min_que[min_front+1]] - data[max_que[max_front+1]]) > k) {

24                 if (min_que[min_front+1] > max_que[max_front+1]) {

25                     now = max_que[++max_front];

26                 } else {

27                     now = min_que[++min_front];       

28                 }                                      

29             }            

30             int dif = abs(data[min_que[min_front+1]] - data[max_que[max_front+1]]);

31             if (dif >= m)

32                ans = max(ans,i-now);        

33         }

34         cout<<ans<<endl;

35     }

36     return 0;

37 }

你可能感兴趣的:(HDU)