【NOI2000T1】瓷片项链-二次函数的最值

    xiaoxiao2021-03-25  108

    测试地址:瓷片项链

    注意,该测试地址中的式子写错了,应该是D=0.3*(V-V0)^0.5(也就是D=0.3*sqrt(V-V0)),漏了一个^0.5,看得我不明所以...找到了原题才知道少了个根号。

    做法:设分成s块,要求总长W=sD最大,化一下式子:

    W=sD=s*0.3*sqrt(V总/s-V0)=0.3*sqrt(V总s-V0s^2)

    注意到根号内的式子(V总s-V0s^2)是一个关于s的二次函数,这个式子越大,W就越大,所以问题转化为求二次函数(V总s-V0s^2)取最大值时s的取值,由于二次项系数小于0,所以函数在顶点处取最大值,由初中的数学知识得bests=V总/(2*V0)。然而,bests可能不是整数,而问题要求整数解,由二次函数的图象可知,离顶点横坐标越接近的点的函数值越大,所以我们就比较bests与其向下和向上取整的整数之间的差的绝对值,与哪个的差值小就选哪个作为真正的bests,如果差值相等,说明有两个整数最优解,按照题目要求输出0。还要注意一点,如果在s=bests时函数值为负数,这种情况是无解的,因为原式没有意义。

    所以总归来说这题还是很水的......完全是初中知识嘛,写起代码来也是只有20多行,多年前的NOI果然水啊。

    以下是本人代码:

    #include <cstdio> #include <cstdlib> #include <iostream> #include <algorithm> #include <cmath> #define e 1e-7 using namespace std; double vt,v0,best,c,ans; int main() { scanf("%lf%lf",&vt,&v0); best=vt/(2*v0); c=(int)best+0.5; if (fabs(best-c)<e) {printf("0");return 0;} else if (best<c) best=(int)best; else best=(int)best+1; ans=0.3*best*sqrt(vt/best-v0); if (ans<0) printf("0"); else printf("%.0lf",best); return 0; }

    转载请注明原文地址: https://ju.6miu.com/read-9781.html

    最新回复(0)