分治搜索
所谓分治,就是将一个大事物分解成若干个易解决小事件。然后再将小事件组合起来就得到了大事件的解了。
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.youkuaiyun.com/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;
}