动态规划的状态求解是一个枚举过程。一些情况下状态枚举的时间复杂度是线性的。这种情况下,如果问题规模比较大时容易出现超时。而我们知道线段树的查询和插入的时间复杂度是nlog(n)。能不能利用线段树的优点,来加速动态规划的状态枚举过程呢?
例1:POJ1631--Bridging signals
本题是求一个序列的最长上升子序列。常规方法的时间复杂度是n^2。如果利用二分,时间复杂度是nlog(n)。现在我们来想能不能利用线段树,来优化常规的方法。
常规解法: 状态max[i]表示第i个数作为最长上升子序列的最后一个元素时的最大值。 求max[i]的最大值,需要枚举第1个元素,第2个元素,...,第i-1个元素的最大值。
[p]我们换一种思路来思考。假设第i个数的大小是value[i],如果第i个数作为最长上升子序列的最后一个元素的话,那么它前面的元素的值只能是1,2,...,value[i]-1(有些值可能没有,因为这些值必须出现在value[1],value[2],...,value[i-1]中)。如果已经知道了1,2,...,value[i-1](不存在的值,对应的最大值为0)作为最长上升子序列的最后一个元素的值的最大值,那么我们能够得到value[i]作为最长上升子序列的最后一个元素的值的最大值。设max[i]表示i作为最长上升子序列的最后一个元素的值的最大值。那么现在的问题变成了,求区间[1,value[i]-1]中,最大的max值。Good!这个问题恰好是线段树的所擅长的。
阅读全文