hdu 2899 Strange fuction(用三分即可 不用求导)

转载亲请注明出处:http://blog.csdn.net/u012860063/article/details/21318849

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=2899


----------------------------------------------------------------------------------------------------------------------------------------------------------
欢迎光临天资小屋害羞害羞害羞害羞http://user.qzone.qq.com/593830943/main

----------------------------------------------------------------------------------------------------------------------------------------------------------



首先简介一下三分思想:

大家都知道二分搜索算法作为分治中最常见的方法,适用于单调函数,逼近求解某点的值。但当函数具有凹凸性时,二分搜索就无法使用了(当然可以先排序),这里介绍一种新的方法,三分查找算法,适应的函数图形如下:

hdu 2899 Strange fuction(用三分即可 不用求导)_第1张图片

算法思想


1. 与二分查找算法类似,先取整个区间的中间值mid
mid = (left + right) / 2;

2. 再去右侧区间的中间值midmid,从而把区间分成三个小区间
midmid = (mid + right) / 2;

3. 如果mid比midmid更靠近最值点,我们就舍弃右区间(midmid + 1 ~ end),否则我们就舍弃左区间(left ~ mid - 1).
比较mid与midmid谁更靠近最值,只需要确定mid所在的函数值与midmid所在的函数值的大小。当最值为最大值时,mid与midmid中较大的那个自然更为靠近最值。最值为最小值时同理
if (cal(mid) < cal(midmid)) 
	left = mid;
else
	right = midmid;

4. 重复1,2,3,直到找到最值点

Strange fuction

Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others)
Total Submission(s): 2712    Accepted Submission(s): 2010


Problem Description
Now, here is a fuction:
  F(x) = 6 * x^7+8*x^6+7*x^3+5*x^2-y*x (0 <= x <=100)
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
   
   
   
   
2 100 200
 

Sample Output
   
   
   
   
-74.4291 -178.8534
 

Author
Redow
 

Recommend
lcy

题意:即求最小值!

代码如下:

#include<cstdio>
#include<cstring>
#include<cmath>
#include<algorithm>
#define EPS 1e-7     //开始的时候设置成五位 一直wa
using namespace std;
int y;
double Calc(double x)
{
    return 6*pow(x,7.0)+8*pow(x,6.0)+7*pow(x,3.0)+5*pow(x,2.0)-y*x;
}
double Solve(void)
{
    double Left, Right;
    double mid, midmid;
    double mid_value, midmid_value;
    Left = 0; Right = 100;
    while (Right - Left > EPS )
    {
        mid = (Left + Right) / 2;
        midmid = (mid + Right) / 2;
        mid_value = Calc(mid);
        midmid_value = Calc(midmid);
        if (mid_value < midmid_value) 
			Right = midmid;
        else 
			Left = mid;
    }
    return Left;
}
int main()
{
    int t;
    scanf("%d",&t);
    while(t--)
    {
        scanf("%d",&y);
        printf("%.4lf\n",Calc( Solve()));
    }
    return 0;
}


赞!不懂请评论提出!

你可能感兴趣的:(算法,二分查找,搜索)