分治搜索(二分,三分)

来源:互联网 发布:国外人工智能机器人 编辑:程序博客网 时间:2024/06/05 08:02

分治搜索

这里写图片描述
所谓分治,就是将一个大事物分解成若干个易解决小事件。然后再将小事件组合起来就得到了大事件的解了。

1.二分搜索:

其中二分搜索是最经典的分治算法。在一个有序连续的单元内,给定键值便可以找到其位置。
算法复杂度O(logN)由此可见其查找的高效性。
接下来结合代码分析:

int BS(int a[],int length,int key){    int left=0,right=length-1;    while(left<=right)    {        int mid=(left+right)/2;        //最终区间会缩小到mid上;因为最后left=right;        if(key<mid)            right=mid-1;        else            if(key==mid)            return mid;            else            left=mid+1;    }    return -1;}

例题练习:http://acm.hdu.edu.cn/showproblem.php?pid=2199
求1~100内方程的解,很明显这是一个增函数。符合有序的搜索条件。
二分搜索。

#include<iostream>#include<cstdio>#include<string>#include<algorithm>#include<cmath>using namespace std;double y;int main(){   int t;   scanf("%d",&t);   while(t--)   {       scanf("%lf",&y);       double left=0,right=100,mid;       if(y>=6&&y<=807020306)       {           double t=8*mid*mid*mid*mid+ 7*mid*mid*mid+ 2*mid*mid+ 3*mid+ 6;           while(fabs(y-t)>0.00001)          {              mid=(right+left)/2.0;              t=8*mid*mid*mid*mid+ 7*mid*mid*mid+ 2*mid*mid+ 3*mid+ 6;              if(t==y) break;              if(t>y)             {                 right=mid;             }             else             {              left=mid;            }        }          printf("%.4lf\n",mid);       }       else        printf("No solution!\n");   }    return 0;}

2.三分搜索

我们都知道 二分查找 适用于单调函数中逼近求解某点的值。
如果遇到凸性或凹形函数时,可以用三分查找求那个凸点或凹点,寻找最值得时候,三分就体现出他巨大的威力。
这里有一篇讲的比较好的博客可以给大家推荐一下:
http://blog.csdn.net/pi9nc/article/details/9666627
我也重新实践一下:

int TS(){    int left=0,right=100,mid;    while(left<right-1)    {        mid=(left+right)/2;        int mmid=(mid+right)/2;        if(fun(mid)<fun(mmid))            right=mmid;        else            left=mid;    }    return mid;}

给一个经典的例题参考:
http://acm.hdu.edu.cn/showproblem.php?pid=2899

就是找最小值。
AC代码:

#include <cstdio>#include <cmath>using namespace std;double ThreeDivide(double x,double Y){    return 6*pow(x,7)+8*pow(x,6)+7*pow(x,3)+5*pow(x,2)-Y*x;       }int main(){    int T,i;    double Y,left,rigth,mid,mmid;    scanf("%d",&T);    while (T--)    {        scanf("%lf",&Y);        left=0,rigth=100;        for (i=1;i<=200;i++)        {            mid=(left+rigth)/2;            mmid=(mid+rigth)/2;            if (ThreeDivide(mid,Y)<ThreeDivide(mmid,Y))                rigth=mmid;            else                left=mid;        }        printf("%.4lf\n",ThreeDivide(mid,Y));    }    return 0;}
原创粉丝点击