二分与贪心

二分

二分法是什么

高中数学必修一对于二分法求方程近似解的介绍是:

对于在区间\([l,r]\)连续的函数\(f(x)\),若使得\(f(l)*f(r)<0\),则该区间内存在一变号零点(零点存在定理)

所以每次不断地将这个区间一分为二,每次判断两个子区间是否满足零点存在定理,即可求得零点的一个近似解

但是这样只能求得一组解

二分查找

在序列上查找一个元素的位置,最暴力的做法当然是便利这个序列,最坏的时间复杂度是\(O(n)\)的。

但是如果我们查找的序列是有序的,那么我们就可以运用二分法以\(O(log_2n)\)单次的复杂度进行查找

请注意,运用二分法通常有如下几个关键词

【连续】 【单调】 【确切答案】

解通常是唯一的,或者干脆不存在

\[Code \]

递归

int Binary_Search(int l,int r,int x)
{
	if(l>r) return -1;
	int mid=(l+r)/2;
	if(a[mid]==x) return mid;
	if(x<a[mid]) return Binary_Search(l,mid-1,x);
	if(x>a[mid]) return Binary_Search(mid+1,r,x);
}

非递归

int Binary_Search(int l,int r,int x)
{
	while(l<=r)
	{
		int mid=(l+r)/2;
		if(a[mid]==x) return mid;
		if(x<a[mid]) r=mid-1;
		else l=mid+1;
	}
	return -1;
}

STL中的二分查找

  • std::lower_bound()

    返回有序列表里第一个大于等于给定值的指针或迭代器

  • std::upper_bound()

    返回有序列表里第一个大于给定值的指针或迭代器

  • std::binary_search()

    返回给定值是否在有序表里存在

用法举例

  • 【例1】

int x=lower_bound(a+1,a+n+1,y)-a-1;

一个非常常见的用途:离散化

void init()
{
	for(int i=1;i<=n;i++)
		a[i]=read(),b[i]=a[i];
	sort(b+1,b+n+1);
	for(int i=1;i<=n;i++)
		a[i]=lower_bound(b+1,b+n+1,a[i])-a-1;//取下标 
}

可以在值域较大的情况下,在保证相对大小不变的情况下缩小值域

这样很多值域相关的操作就可以女进行,例如树状数组逆序对

  • 【例2】
int a[5]={0,2,4,6,8};
printf("%d %d %d\n",lower_bound(a,a+5,2)-a,upper_bound(a,a+5,2),binary_search(a,a+5,2));
printf("%d %d %d\n",lower_bound(a,a+5,3)-a,upper_bound(a,a+5,3),binary_search(a,a+5,3));

输出结果

输出结果

在map/set里面的用法

a.lower_bound(2)

注意STL的迭代器不可减

毕竟这个本质是平衡树,哪来的下标,是吧

二分查找的实质

可以把数组看做值离散的函数

二分查找的实质就是定义在(定义域为整数的)函数的二分法

但是相比之下,二分查找对数组有单调性的要求,并且保证可以找到答案

二分答案

可以使用二分答案的题目的答案,会具有某种单调性

以及一些提示性的关键词:【最大值最小】【最小值最大】等

这类题目的思想大概就是:我们知道了答案满足这样的单调性,所以我们在答案的取值范围内进行二分,每次验证一个解

算法模板和之前的二分法求方程近似解非常像,不过会讨一个奇奇怪怪的函数检查生成的答案的正确性

通常来说,二分答案题目分为下列两种中的一种:

  1. 给定一个评价函数,求评价函数的最小/大值

  2. 给定一个条件,要求在满足条件的同时,使得代价最小

计算函数或者判断符合条件需要消耗极长的时间

或者说评价函数的值域太大了,不能一一计算

感性理解一下二分答案

感性理解一下二分答案

模板

//假设我们这里要求最小值
int find(int l,int r)
{
	while(l<r)
	{
		int mid=(l+r)/2;
		if(check(mid)) r=mid;
		else l=mid+1;
	}
	return -1;
} 
//对于大多数题目而言,难点在于如何设计这个check()函数

贪心

什么是贪心

在每一步选择中都采取在当前状态下最好或最有(即最有利)的选择,从而希望导致结果是最好或最有的算法

说白了,这个算法的事情就和他的命自已样,每一步贪心的进行一种选择

当然,贪心不是具体的算法,而是一种思想

不资瓷一下吗QAQ

posted @ 2021-08-15 20:53  晨曦时雨  阅读(118)  评论(0)    收藏  举报
-->