尺取、二分、三分(函数模板)

尺取、二分、三分(函数)

一、尺取
设置两个下标表示区间的左右端点,根据实际情况推进两个端点求得答案。

/**
	给定一个序列a,求a中元素和大于等于s的子序列的最小长度
	(保证a中元素都为正)
*/

int take() //尺取
{
    int l=1,r=1;
    int sum=a[1],ans=inf;
    while(r<=n)				//s是要查找的元素
    {
        if(sum<s) sum+=a[++r];
        else
        {
            while(sum>=s)
            {
                ans=min(ans,r-l+1);
                sum-=a[l++];
            }
        }
    }
    return ans;
}

二、二分
查找x第一次出现的位置

/**
	有一个序列a,a中元素满足单调递增(任意下标i和j满足i<j,则ai<aj)。
	查找a中元素q在a中第一次出现的位置。
*/
int binary_first(int x) //二分查找x第一次出现的位置
{
    int l=1,r=n;			//n是数组大小
    while(l<r)
    {
        int bet=(l+r)/2;
        if(a[bet]<x) l=bet+1;
        else r=bet;
    }
    return l;
}

查找x最后一次出现的位置

/**
	有一个序列a,a中元素满足单调递增(任意下标i和j满足i<j,则ai<aj)。
	查找a中元素q在a中最后一次出现的位置。
*/
int binary_last(int x) //二分查找x最后一次出现的位置
{
    int l=1,r=n;			//n是数组大小
    while(l+1<r)
    {
        int bet=(l+r)/2;
        if(a[bet]<=x) l=bet;
        else r=bet-1;
    }
    return a[r]==x?r:l;
}

C++还有两个函数:

lower_bound() 	返回a中第一个大于等于x的元素下标  
upper_bound() 	返回a中第一个大于x的元素的下标

三、三分

/**
	计算凸(凹)函数的最大值(最小值)。
*/
void thrp() //三分
{
    double l=1,r=n;			//n是数组大小
    while(r-l>=eps)			//eps是精度,题目会有要求
	{
		m1=l+(r-l)/3;
		m2=r-(r-l)/3;
		if(f(m2)-f(m1)>=eps)
		  l=m1;
		else
		  r=m2;
	}
	return l;
}
发布了60 篇原创文章 · 获赞 69 · 访问量 2822

猜你喜欢

转载自blog.csdn.net/qq_45856289/article/details/104543394