从零开始刷HDOJ(3)【HDOJ2899

来源:互联网 发布:最短路径的floyd算法 编辑:程序博客网 时间:2024/06/05 20:40

从零开始刷HDOJ(3)【HDOJ2899 - Strange function 】

题面

Strange fuction

Time limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)Total Submission(s): 7321 Accepted Submission(s): 5057

Problem Description

Now, here is a function:

F(x)=6x7+8x6+7x3+5x2yx(0x100)

Can you find the minimum value when x is between 0 and 100.

Input

The first line of the input contains an integer T(1<=T<=100) which means the number of test cases. Then T lines follow, each line has only one real numbers Y.(0 < Y <1e10)

Output

Just the minimum value (accurate up to 4 decimal places),when x is between 0 and 100.

Sample Input

2100200

Sample Output

-74.4291-178.8534

提交传送门:Submit

翻译

​ 就是把求一下当y等于你输入的值时F(x)在[0, 100]上的零点。

思路

​ 其实这个函数在[0, 100]上是单峰的。

Proof:

(kxμ)=kμ(x)(μ1)

F(x)=42x6+48x5+21x2+10xy

y=ax6[0,100]y=ax5[0,100]y=ax2[0,100]y=ax[0,100]

F(x)[0,100]

​ 既然我们可以证明F(x)的导函数F(x)在定义域单调增,那么我们就可以在定义域中二分零点(具体方法参考高中数学必修一),找到的这个点就是我们要求的取值点了。最后输出F(ans)就好了。

代码

#include <cmath>#include <iostream>// F(x) = 6x7 + 8x6 + 7x3 + 5x2 – xy double y;inline double f(const double x){    return 6 * std::pow(x, 7) + 8 * std::pow(x, 6) + 7 * std::pow(x, 3) + 5 * std::pow(x, 2) - y * x;}inline double F(const double x){    return 42 * std::pow(x, 6) + 48 * std::pow(x, 5) + 21 * std::pow(x, 2) + 10 * x;}int main(int argc, char ** argv){    std::ios_base::sync_with_stdio(false);    std::cout.setf(std::ios_base::fixed);    std::cout.precision(4);    double ans;    double l = 0.0, r = 100.0;    int times = 1000;    int T;    std::cin >> T;    while (T--)    {        std::cin >> y;        l = 0.0;        r = 100.0;        times = 10000;        double eps = 1e-10;        while (times--)        {            double mid = (l + r) / 2.0;            if (F(mid)>y)                r = mid;            else                l = mid;        }        std::cout << f(l) << std::endl;    }    std::cin.get();    std::cin.get();    return 0;}
原创粉丝点击