三分算法前人之述备矣了,咱们只需要看并且学习就好了。
几篇高质量博客
https://blog.csdn.net/Littlewhite520/article/details/70144763
https://blog.csdn.net/pi9nc/article/details/9666627
寻找区间最大值
int Three_Search(int n)
{
int L = 1;
int R = n;
int mid, mmid; // mid 和 R的中点
while (L < R - 1)
{
// cout << L << " " << R<< endl;
mid = (L + R) >> 1;
mmid = (mid + R) >> 1;
if (a[mid] > a[mmid])
R = mmid;
else
L = mid;
}
return a[L] < a[R] ? L : R;
}
寻找区间最小值
int Three_Search(int n)
{
int L = 1;
int R = n;
int mid, mmid; // mid 和 R的中点
while (L < R - 1)
{
mid = (L + R) >> 1;
mmid = (mid + R) >> 1;
if (a[mid] < a[mmid])
R = mmid;
else
L = mid;
}
return a[L] < a[R] ? L : R;
}
2020牛客第五场 B题
题目链接 https://ac.nowcoder.com/acm/contest/3006/B
这题就是一个运用三分算法寻找凸函数最大值的例子。
附上代码 跟题解几乎一样
#include <iostream>
#include <malloc.h>
#include <cstdio>
#include <algorithm>
#include <queue>
#include <cmath>
#include <map>
#include <cstring>
#define IO \
ios::sync_with_stdio(false); \
cin.tie(0); \
// cout.tie(0);
using namespace std;
typedef long long LL;
const int maxn = 100000 + 10;
struct p
{
int x, y;
} p[maxn];
int n;
double dist(double x)
{
double max = 0;
for (int i = 1; i <= n; i++)
{
double t = sqrt(p[i].y * p[i].y + (p[i].x - x) * (p[i].x - x));
if (t > max)
max = t;
}
return max;
}
double Three_Search(double L, double R)
{
int i;
double mid, mmid;
for (i = 0; i < 100; i++) // 靠着循环次数不断逼近最大值嗯应该是这样
{
mid = L + (R - L) / 2;
mmid = mid + (R - mid) / 2;
if (dist(mid) > dist(mmid)) //极大值求法
L = mid;
else
R = mmid;
}
return mid;
}
int main()
{
#ifdef ONLINE_JUDGE
#else
freopen("in.txt", "r", stdin);
// freopen("out.txt", "w", stdout);
#endif
scanf("%d", &n);
for (int i = 1; i <= n; i++)
scanf("%d%d", &p[i].x, &p[i].y);
double max = Three_Search(-10000, 10000); // 左右区间
printf("%.4lf\n", dist(max));
return 0;
}