大意就是给你一个函数,然后让你求这个函数的最小值
正解是一个导函数加二分
F(x) = 6 * x^7+8*x^6+7*x^3+5*x^2-y*x (0 <= x <=100) QAQ我不会求导
然后就用了模拟退火?但是没用随机数QAQ 做得懵懵懂懂的
因为HDU POJ都不支持万能头文件过分!所以我就复制一篇题解的头文件
1 #include<iostream> 2 #include<cstdio> 3 #include<cmath> 4 using namespace std; 5 const double eps=1e-6,delta=0.96;//精度eps(温度的下界) 6 double y; 7 int chan[2]={1,-1};//自变量变化 8 9 double f(double X)//函数 10 { 11 return 6*pow(X,7)+8*pow(X,6)+7*pow(X,3)+5*pow(X,2)-y*X; 12 } 13 14 int main() 15 { 16 int T;scanf("%d",&T); 17 while(T--) 18 { 19 scanf("%lf",&y); 20 double x=0,t=100;//自变量 初始温度 21 while(t>eps) 22 { 23 for(int i=0;i<2;i++) 24 { 25 double nxtx=x+t*chan[i]; 26 if(nxtx<0||nxtx>100) continue; 27 if(f(nxtx)<f(x)) x=nxtx;//如果更优 替换 28 } 29 t*=delta;//降温 30 } 31 printf("%.4f ",f(x)); 32 } 33 return 0; 34 }
QAQ就搞不懂为什么我用的实数快读要超时,然后改用scanf读入就过了
inline double dbread()//正负实数读入优化 { double x=0,y=1.0; int w=0; char ch=0; while(!isdigit(ch)) {w|=ch=='-';ch=getchar();} while(isdigit(ch)) x=x*10+(ch^48),ch=getchar(); ch=getchar();//读入小数点 while(isdigit(ch)) x+=(y/=10)*(ch^48),ch=getchar(); return w?-X:X; }
delta为0.98时用时46ms 为0.96时为31ms QAQ前面几个是万能头文件和用实数快读超时