题意:
f ( X) = | a x^3+b x^2 + c x + d |; 给定a, b, c , d的值,和 x 的范围,求函数值的最大值。
分析: 1,当然要求导,并判断 b^2 - 4*a*c d 的范围。
2,注意a=0,b=0的时候。
3,判断极值的点和边界点作比较,找最大值。
注意点: 避免精度误差。
const double eps=1e-9;
double a,b,c,d,L,R;
double fun(double x )
{
if(x>=L&&x<=R)
{
return fabs(a*x*x*x+b*x*x+c*x+d);
}
return -1;
}
double solve(double a,double b,double c)
{
if(fabs(a)<eps)
{
if(fabs(b)<eps)
return -1;
else
return fun(-c/b);
}
double sum=b*b-4*a*c;
if(sum>0)
{
sum=sqrt(sum);
return max(fun((-b+sum)/2.0/a),fun((-b-sum)/2.0/a));
}
return -1;
}
int main()
{
while(scanf("%lf%lf%lf%lf%lf%lf",&a,&b,&c,&d,&L,&R)!=EOF)
{
double ant=max(fun(L),fun(R));
ant=max(ant,solve(3*a,2*b,c));
printf("%0.2lf\n",ant);
}
return 0;
}
题意: 求极值点,找最小值:
解法: 牛顿迭代法,X = X — F(X) \ F1(X) ( F1(X) 为 F(X)的导数 )
#include<iostream>
# include<cstdio>
#include<cmath>
using namespace std;
#define f(x) 6*x*x*x*x*x*x*x + 8*x*x*x*x*x*x + 7*x*x*x +5*x*x -Y*x
#define f1(x) 42*x*x*x*x*x*x + 48*x*x*x*x*x + 21*x*x + 10*x - Y
# define f2(x) 252*x*x*x*x*x + 240*x*x*x*x + 42*x + 10
#define G(x) x - (f1(x))/(f2(x))
double Y;
#define exp 1e-6
double New_iteration(double x)
{
int k=1;
while(fabs(f1(x))>exp) // 注意取绝对值
{
x = G(x);
k++;
if(k>10) return -1; //注意迭代次数,最多大于30
}
return x;
}
int main()
{
int t;
cin>>t;
while(t--)
{
double l=0;
double r=100;
double m;
scanf("%lf",&Y);
if(f1(l)>0)
printf("%0.4lf\n",f(l));
else if(f1(r)<0)
printf("%0.4lf\n",f(r));
else
{
for(double i=0;i<100;i++) //按照范围遍历查找
{
m = New_iteration(i);
if(m>=l&&m<=r)
{
printf("%0.4lf\n",f(m)); break;}
}
}
}
return 0;
}
hdu 2289 cup
题意和分析: 用到圆台的体积公式。 经过转换之后就是求杯中热水的高度的一元二次方程,求极值。
注意点: 函数的频繁调用会造成精度损失
#define pi acos(-1.0)
#define g(h) h/H*(R-r)+r
#define V(h) pi/3 * h * ( ss*ss+ss*r+r*r) - v //注意点:函数的频繁调用会造成精度损失
#define eps 1e-10
注意点: (runtime error) ACCESS VIOLATION 访问冲突,超内存,可能是数组开小。 另外3个for 循环易超时。
对于 A+B+C ==X 的一类问题,注意转化为 A+B == X - C