hdu 3530 单调队列 Subsequence

Posted: March 31, 2011 in Uncategorized

题目描述http://acm.hdu.edu.cn/showproblem.php?pid=3530

大意:有一个序列,找出满足最大值小于等于k,最小值大于m的子序列中最长的一个,输出长度。

状态表示:F[i]:以i为结束点的序列满足m,k的条件的最大值。如果从后向前扫描统计最大值和最小值,这样时间复杂度为O(n*n).

通过分析发现:

max[i-1,j+1] >= max[i,j] and min[i-1,j+1] <= min[i,j];令p[i,j] = max[i,j] – min[i,j]

即:设p[i,j]随着i的增加,p[i,j]下降;随着j的增加,p[i,j]增加。

1.F[j] = min{i: p[i,j] <= k},i的取值范围,随着j的增加,i值不减。if: p[i,j] > k then:p[i,j+1] >k

2.当得到p[i,j] <= k的最小i后,如果p[i,j] < m 那么 p[i+1,j] <m,即:如果满足k后如果不满足m,那么后面的值都不满足。

通过以上的分析,我们的目标就是找到关于j的p[i,j] <= k的最小i,这个值i值取值范围只增不减。

于是可以使用单调队列来优化,设计一个i值指针,代表对于j可以取的最小值为i。两个单调队列,分别表示i以后到j的最大值和最小值。如果当前的i值,p[i,j] > k,那么取下一个最大值或者最小值,由于要去i值最小,i值增加到两个队列中小的下标。在求最小i值的过程中统计对于每个j的最长序列值。

算法的时间复杂度降到了O(n).

PS:

在实现的时候,错误地将最优解的初始值定为了-1,其实应该是0,如果都没有满足的序列,序列最长应该是0.

Leave a comment