一道简单的三分求最值题.
对F[x]进行求导得:F'[x]=42*x^6+48*x^5+21*x^2+10*x-y;
因为f(x)=42*x^6+48*x^5+21*x^2+10*x,在[0,100]上是增函数,
所以F'[x]=42*x^6+48*x^5+21*x^2+10*x-y,至多只能有一个零点,
所以可以确定F[x]在[0,100]上可能是单调函数或凹函数,所以可以用
三分求解这个函数的最小值。
但经过上面分析后,我们发现其实也可以按y值分类讨论;当F[x]单调时,直接输出结果
,当F[x]为凹函数时,二分求出其导函数的零点,则零点对应的函数值就是我们要求的最小值。
这个思路对于代码二
代码如下:
#include<iostream>
#include<cstring>
#include<cstdio>
#include<cmath>
using namespace std;
double y;
double f(double x)
{
return 6*pow(x,7.0)+8*pow(x,6.0)+7*pow(x,3.0)+5*pow(x,2.0)-y*x;
}
int main()
{
int t;
cin>>t;
while(t--)
{
cin>>y;
double first=0.0,last=100.0;
while(last-first>1e-6)
{
double mid=(first+last)/2;
double midmid=(mid+last)/2;
if(f(mid)>f(midmid))
first=mid;
else
last=midmid;
}
double ans=f((first+last)/2);
printf("%.4f\n",ans);
}
return 0;
}
代码二:
<span style="font-size:18px;">//二分求解浮点型方程
#include<iostream>
#include<cstring>
#include<cstdio>
#include<cmath>
using namespace std;
double y;
double f(double x)
{
return 6*pow(x,7.0)+8*pow(x,6.0)+7*pow(x,3.0)+5*pow(x,2.0)-y*x;
}
double f1(double x)
{
return 42*pow(x,6.0)+48*pow(x,5.0)+21*pow(x,2.0)+10*x;
}
int main()
{
int t;
double ans;
cin>>t;
while(t--)
{
cin>>y;
if(y<=0)
{
ans=0.0;
printf("%.4f\n",ans);
continue;
}
if(y>=f1(100.0))
{
ans=f(100.0);
printf("%.4f\n",ans);
continue;
}
double first=0.0,last=100.0;
while(last-first>=1e-7)
{
double mid=(first+last)/2;
if(f1(mid)<=y)
first=mid+1e-10;
else
last=mid-1e-10;
}
ans=f((first+last)/2);
printf("%.4f\n",ans);
}
return 0;
} </span>