HDU.2899.Strange fuction(牛顿迭代)
Posted sovietpower
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了HDU.2899.Strange fuction(牛顿迭代)相关的知识,希望对你有一定的参考价值。
(Description)
求函数(F(x)=6 imes x^7+8 imes x^6+7 imes x^3+5 imes x^2-y imes x)在(xin left[0,100 ight])时的最小值。
(Solution)
(xgeq 0)时(F(x))为单峰凹函数,三分即可。
而且由此可知(F(x))的导数应是单增的。函数最值可以转化为求导数零点问题,于是也可以二分求(F'(x))的零点,或者用牛顿迭代求。
峰值函数最值也可以用模拟退火求。
练习下牛顿迭代。其它代码可以见这。
牛顿迭代:[x=x_0-frac{F(x_0)}{F'(x_0)}]
对(F(x))泰勒展开,(F(x)=F(x_0)+F'(x_0)(x-x_0)+frac{F''(x_0)}{2!}(x-x_0)^2+ldots+frac{F^{(n)}(x_0)}{n!}(x-x_0)^n+R_n(x))
为方便计算?只保留线性部分(F(x)=F(x_0)+F'(x_0)(x-x_0))
就可以得到(x=x_0-frac{F(x_0)}{F'(x_0)})
多次迭代、多次选取(x_0)即可。
//0MS 1628K
#include <cmath>
#include <cstdio>
#include <algorithm>
#define eps (1e-7)
double y;
inline double f(double x){
return 6*pow(x,7)+8*pow(x,6)+7*pow(x,3)+5*x*x-y*x;
}
inline double fd(double x){
return 42*pow(x,6)+48*pow(x,5)+21*x*x+10*x-y;
}
inline double fdd(double x){
return 252*pow(x,5)+240*pow(x,4)+42*x+10;
}
double Get_zero(double x)
{
double las=x+1;
while(fabs(las-x)>eps) las=x, x=x-fd(x)/fdd(x);
return x;
}
int main()
{
int T; scanf("%d",&T);
while(T--)
{
scanf("%lf",&y);
double ans=1e15;
for(int i=0; i<=100; i+=10) ans=std::min(ans,f(Get_zero(i)));
printf("%.4lf
",ans);
}
return 0;
}
以上是关于HDU.2899.Strange fuction(牛顿迭代)的主要内容,如果未能解决你的问题,请参考以下文章
hdu 2899 Strange fuction——模拟退火
hdu2899Strange fuction(解方程+二分)