ACM入门之【三分】

14 阅读2分钟

介绍

三分算法是什么?

三分算法(Ternary Search)是用于在某一个 单峰区间上 寻找最值(最大值或最小值)的一种算法。

  • 单峰函数 是指在某一段区间上,函数值先单调上升(或下降),再单调下降(或上升)。
  • 适用于连续值(浮点型)或整数值。

特别要注意并不是每个单峰函数都是可以三分的!

某些问题的函数可能是单峰的,但峰值两边并非是严格递增(递减)的,即有可能出现“平台”(一条与 x 轴平行的直线)。

二分算法和三分算法的区别?

特点二分算法三分算法
应用场景查找某个“确定的值”查找一个最值(极值)
单调性要求函数是单调的(增或减)函数是单峰的
中点数取一个中点取两个中点 mid1mid2
目标找一个值/判定某个条件找函数值的最大或最小值

三分算法的基本原理

假设你在一条山路上徒步,你想找到最高点(或最低点),这时候你知道地形是单峰的:

    1. 你在区间 [l, r] 中,选取两个点:mid1 = l + (r - l) / 3,mid2 = r - (r - l) / 3
    1. 计算这两个点的函数值:f(mid1)f(mid2)
    1. 比较两者:
    • 如果 f(mid1) < f(mid2),说明峰值在 mid1r 之间。
    • 如果 f(mid1) >= f(mid2),说明峰值在 lmid2 之间。
    • 如果两者相等,也可以缩小区间 [mid1, mid2]
    1. 重复这个过程,直到区间非常小,就可以近似找到最值。

板子

单峰函数(凸)函数
double ternary_search(double l, double r) {
    while (r - l > 1e-7) {
        double mid1 = l + (r - l) / 3;
        double mid2 = r - (r - l) / 3;
        if (f(mid1) < f(mid2))
            l = mid1;
        else
            r = mid2;
    }
    return (l + r) / 2;
}

单谷(凹)函数
double ternary_search(double l, double r) {
    while (r - l > 1e-7) {
        double mid1 = l + (r - l) / 3;
        double mid2 = r - (r - l) / 3;
        if (f(mid1) > f(mid2))
            l = mid1;
        else
            r = mid2;
    }
    return (l + r) / 2;
}

习题

游游开车出游

P3382 三分