一.单调队列
用途: 在长度为n的数组中,从1到n-m+1分别为起点的连续的m个区间长度中求出最大值或最小值(即求某个区间内的最值)
基本思想: 维护队首元素作为答案,去掉多余的元素(维护队列单调性)。
假设现在我们维护一个递减(用来求最大值)的单调队列,当一个数据想要入队时,需要执行以下操作:
I. 从队尾到队首开始遍历,如果碰到元素比待入队元素要小,那么这个元素便失去了作用(因为维护的是最大值,如果有一个比当前值小,那它一定不是最大的),将其出队。直到碰到一个比当前值大的元素,跳出循环;(在执行 I 之后,队列中所有之前元素都比当前元素大)
II. 从队首开始清除已经不符合条件的元素(比如已经“过时”即不在当前区间内的元素,视题目而定);(执行 II 之后,队列中不再有“过时”元素,即此时队列中只有在区间内而且队首元素就是最大值。)
时间复杂度: 每个元素最多进队一次,出队一次,总复杂度O(n)。大大减小了两个for循环找某一区间的最值的复杂度O(n^2)
单调队列与优先队列的相同与区别:
相同:它们的单调性都是单调递减或单调递增;都是维护队首元素作为答案。
区别:单调队列求的是某个特定题目给定的区间的最值,而优先队列求的是整个输入长度区间的最值
二. 二分法
用途:I. 用于处理单调区间上的极值问题。
II. 给出问题中两个变量之间存在正比或反比关系,可对一个变量进行二分,进而求出另一变量的最优解。
III. 求最小值的最大以及求最大值的最小问题
三.闲碎知识点
I. 比较实型变量d是否为0一般用fabs(d)<=1e-7来判断。
II. printf()格式化输出函数
%lf 是printf函数在输出 double 类型时用到的格式符。
使用 %lf 时,可以在 “%” 和 "lf" 之间指定要输出的 double 类型的【整个数字长度】和【小数部分部分】,他们之间用"."分开,这两部分可以任意一个或者两个都空着不写。
其中【整个数字长度】是包括,整数部分长度,小数部分长度(包括小数点,如有有小数部分的话)一共两个部分的。下面这些写法都是合法的:
(1) %lf
(2) %.lf
(3) %10.lf
(4) %.10lf
(5) %10.10lf
(6) %10lf如果【小数部分指定输出长度】缺省,不足的部分用“0”补齐。比如有数字123.45,使用“%10lf” ,整体输出123.450000
如果【小数部分指定输出长度】明确指定,那么按指定的长度输出【小数部分】,不足部分用“0”补齐。
比如有数字123.45,使用“%.10lf” ,整体输出为123.4500000000如果【整个数字的输出长度】为空或缺省,那么会输出完整的整数部分。
如有数字 123456.78,使用 “%.f” 输出,那么整数部分的输出为:123456,实际输出长度为6。如果【整个数字的输出长度】 明确指定 。那么【整数部分的输出长度】分为分两种情况讨论:
1)
比如有数字 123.45 ,使用“%5.4lf”输出。最后输出:123.4500
2)
比如有数字 123.45 ,使用“%10.4lf”输出。也就是说整数部分输出长度为5,而整数部分的实际长度为3,所以要补充:5-3=2个空格进行补齐。
最后输出:" 123.4500"(1前面有两个空格)