f(x)=|ax3+bx2+cx+d|
求f(x)在L≤x≤R的最大值。
参数有可能是0,注意分类讨论
1.当a=0时
b=0,f为一次函数(c≠0)或者常数函数(c=0),最大值点在区间端点。
b≠0,f为二次函数,最大值点在区间端点或者x0=c/(2*b),当L≤x0≤R时,ans=max{f(L),f(R),f(x0)}。
2.当a≠0时,f为三次函数
最大值点在区间端点或者导函数的零点x1,x2。
注意x1,x2是否在[L,R]区间。
#include<cstdio> #include<algorithm> #include<cmath> #define dd double using namespace std; dd a,b,c,d,l,r; dd f(dd x) { return fabs(a*x*x*x+b*x*x+c*x+d); } void ff(dd a,dd b,dd c,dd& ans) { if(a==0) { if(b==0) return; ans=max(ans,f(-c/b)); return; } if(b*b<4*a*c) return; dd q=sqrt(b*b-4*a*c); dd x1=(-q-b)/(2*a); dd x2=(q-b)/(2*a); if(l<x1&&x1<r) { ans=max(ans,f(x1)); if(r>x2) ans=max(ans,f(x2)); } else if(l<x2&&x2<r) ans=max(ans,f(x2)); } int main() { while(~scanf("%lf%lf%lf%lf%lf%lf",&a,&b,&c,&d,&l,&r)) { dd ans; ans=max(f(l),f(r)); ff(3*a,2*b,c,ans); printf("%.2lf\n",ans); } return 0; }
下面这样写,省了判断区间和顶点的不同位置关系。
#include<cstdio> #include<algorithm> #include<cmath> #define dd double using namespace std; dd a,b,c,d,l,r,ans; dd f(dd x) { if(x<l||x>r)return -1; return fabs(a*x*x*x+b*x*x+c*x+d); } dd ff(dd a,dd b,dd c) { if(a==0) { if(b==0) return -1; return f(-c/b); } if(b*b<4*a*c) return -1; dd q=sqrt(b*b-4*a*c); dd x1=(-q-b)/a; dd x2=(q-b)/a; return max(f(x1/2),f(x2/2)); } int main() { while(~scanf("%lf%lf%lf%lf%lf%lf",&a,&b,&c,&d,&l,&r)) { ans=max(f(l),f(r)); ans=max(ans,ff(3*a,2*b,c)); printf("%.2lf\n",ans); } return 0; }
原文:http://www.cnblogs.com/flipped/p/5245237.html