给一函数,该函数在任意Y>0的情况下x在[0,100]内有极小值,求之。
如图这种情况先减后增有极小,若lm比rm低(即lm对应的函数值 < rm函数值)则极小点(图中最低点)肯定在[ left, rm ] ,反之在[ lm, right ],剩下就跟二分一样根据大小关系调整区间就行了。那lm和rm取值多少?一个不错的取值是lm为整个区间的1/3点,rm为2/3点,即
lmid = l + (r - l)/3;
rmid = r - (r - l)/3;
如图lm低于rm,则极大在[ lm,right ].否则极大在 [ left, rm ]。写代码上就是极小的处理语句反过来就行了。
代码:
#include<cstdio>
#include<iostream>
#include<algorithm>
using namespace std;
//从例图看,该函数是单峰凹函数
double y;
double val(double x){
return 6*x*x*x*x*x*x*x+8*x*x*x*x*x*x+7*x*x*x+5*x*x-y*x;
}
double solve(double l.double r){
double eps = 1e-7;
while(l+eps<r){ //r-l>1e-7 误差允许范围
double lmid = l + (r-l)/3,rmid = r + (r-l)/3;
if(val(lmid)<val(rmid)){
r = rmid;
}else{
l = lmid;
}
}
return val(l);
}
int main(){
int t;
cin>>t;
while(t--){
cin>>y;
printf("%.4f\n",solve(0,100.0));
}
return 0;
}