三分查找
P3382 【模板】三分法
思路:根据二分的思路,我们要逼近中间的值,就要确定是
l
e
f
t
left
left还是
r
i
g
h
t
right
right向中间趋近。所以我们设置两个中间值
l
m
lm
lm,
r
m
rm
rm,分别为
l
e
f
t
left
left和
r
i
g
h
t
right
right的下一步趋近值。这样我们比较一下
l
m
lm
lm,
r
m
rm
rm的多项式值,确定下一步的
l
e
f
t
left
left和
r
i
g
h
t
right
right,重复,直到退出循环找到答案。
凸函数
#include<bits/stdc++.h>
using namespace std;
const int N = 1e1+10;
const double eps = 1e-5;
double s[N];
//快速幂
double qpow(double x, int y) {
double ans = 1;
while(y) {
if(y & 1) ans = ans * x;
x = x * x;
y >>= 1;
}
return ans;
}
//计算多项式
double C(double x, int n) {
double ans = 0;
for(int i=0; i<=n; i++) {
ans += qpow(x, n-i)*s[i];
}
return ans;
}
int main() {
#ifndef ONLINE_JUDGE
freopen("in.txt", "r", stdin);
freopen("out.txt", "w", stdout);
#endif
int n;
double x, y;
cin >> n >> x >> y;
for(int i=0; i<=n; i++) cin >> s[i];
double l = x, r = y, lm, rm;
while(r-l > eps) {
lm = (l + r)/2, rm = (lm + r)/2;
if(C(lm, n) > C(rm, n)) r = rm;
else l = lm;
}
cout << l << endl;
return 0;
}
凹函数
#include<bits/stdc++.h>
using namespace std;
const int N = 1e1+10;
const double eps = 1e-5;
double s[N];
double qpow(double x, int y) {
double ans = 1;
while(y) {
if(y & 1) ans = ans * x;
x = x * x;
y >>= 1;
}
return ans;
}
double C(double x, int n) {
double ans = 0;
for(int i=0; i<=n; i++) {
ans += qpow(x, n-i)*s[i];
}
return ans;
}
int main() {
#ifndef ONLINE_JUDGE
freopen("in.txt", "r", stdin);
freopen("out.txt", "w", stdout);
#endif
int n;
double x, y;
cin >> n >> x >> y;
for(int i=0; i<=n; i++) cin >> s[i];
double l = x, r = y, lm, rm;
while(r-l > eps) {
lm = (l + r)/2, rm = (lm + r)/2;
if(C(lm, n) > C(rm, n)) l = lm;
else r = rm;
}
cout << l << endl;
return 0;
}