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


    测试地址:瓷片项链

    注意,该测试地址中的式子写错了,应该是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;
    }
    


  • 相关阅读:
    容斥原理学习(Hdu 4135,Hdu 1796)
    ACdream 1112
    CodeChef--Cards, bags and coins
    ACdream 1108(莫队)
    Hdu 2586(LCA)
    CodeChef--EQUAKE
    Hackerrank--Mixing proteins(Math)
    Clash Credenz 2014 Wild Card Round题解
    Codeforces 463D
    CodeChef August Lunchtime 2014 题解
  • 原文地址:https://www.cnblogs.com/Maxwei-wzj/p/9793833.html
Copyright © 2020-2023  润新知