一、二分
二分最基本的用途是用来对一个有序数列二分查找元素,由于二分的时间复杂度仅为O(log n),又是还可以用于枚举可能的答案进行判定,即为二分答案。考试时考的最多的也是二分答案(毕竟二分查找都有STL写好的函数了...)。
二分答案题型总结:
能用二分答案做的题一般都有单调性,即在某个限度内,劣与这个限度的答案都满足题意但不是最优,而比这个限度最强的答案则不能满足题意。我们就要通过二分的方法把这个限度求出来。例如最大值最小化问题(或最小值最大化问题),和一部分最优化问题。
二分答案的优点在于将最优值的求解转化为可行性判定问题,时间复杂度为O(log n * 判定的复杂度)。而判定又常常用到贪心,甚至又要套上一个二分。
二分要注意定义域为整数还是实数会影响到二分循环的判断条件,偶尔还会有精度问题——当然是在时间特别充足的时候越精确越好啦。
二、三分
对于一个极值的两侧都严格单调的单峰函数,我们常常用三分去求它的极值。原理为:一段包含极值的两个三等分点中较优的会与极值点一起,在另一个三等分点的同一侧。注意维护区间时左右端点对应的三等分点顺序就好。
三分核心代码(这里以定义域为实数的为例)
1 while(r-l>=0.000001) 2 { 3 m1=l+(r-l)/3; 4 m2=r-(r-l)/3; 5 if(check(m1)>=check(m2)) r=m2;//这里以更大为更优 6 else l=m1; 7 }