关于二分

.二分法

在一段单调区间上不断二分寻找关键字(根据二分中值和关键字的比较确定答案区间)
二分法最关键的内容--------二分的判断条件和操作,跳出二分的时机。
二分查找法的O(log n)让它成为十分高效的算法。不过它的缺陷却也是那么明显的。
就在它的限定之上:
必须有序,我们很难保证我们的数组都是有序的。当然可以在构建数组的时候进行排序,
可是又落到了第二个瓶颈上:它必须是数组。
数组读取效率是O(1),可是它的插入和删除某个元素的效率却是O(n)。
因而导致构建有序数组变成低效的事情。
二分查找------时间复杂度----O(logn)
递归查找:
int binary_search(int a[],int low,int high,int key)
{
if(low>high)
return -1;
int mid=(high+low)/2;
if(a[mid]==key)
return mid;
if(a[mid]<key)
search(a,mid+1,high,key);
else
search(a,low,mid-1,key);
}
非递归查找:
int binary_search(int a[],int length,int key)
{
int low=0;
int high=length-1;
int mid=(low+high)/2;
while(low<=high)
{
mid=(low+high)/2;
if(a[mid]==key)
return mid;
if(a[mid]<key)
low=mid+1;
else
high=mid-1;
}
}
二分答案与二分查找类似,即对有着单调性的答案进行二分,大多数情况下用于求解满足某种条件下的最大(小)值。
符合范围的最小值-----check条件为,大于某个范围。
int binary(int n)
{
int left=0,right=n-1,mid;
while(left<right)
{
mid=(left+right)/2;
if(check(mid))
right=mid;
else
left=mid+1;
}
return left;
}
符合范围的最大值-----check条件为,小于某个范围
int binary(int n)
{
int left=0,right=n-1,mid;
while(left<right)
{
mid=(left+right+1)/2;
if(check(mid))
left=mid;
else
right=mid-1;
}
return left;
}
HDU
The Frog’s Games
Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65768/65768 K (Java/Others)
Total Submission(s): 10222 Accepted Submission(s): 4652

Problem Description

The annual Games in frogs’ kingdom started again. The most famous game is the Ironfrog Triathlon. One test in the Ironfrog Triathlon is jumping. This project requires the frog athletes to jump over the river. The width of the river is L (1<= L <= 1000000000). There are n (0<= n <= 500000) stones lined up in a straight line from one side to the other side of the river. The frogs can only jump through the river, but they can land on the stones. If they fall into the river, they
are out. The frogs was asked to jump at most m (1<= m <= n+1) times. Now the frogs want to know if they want to jump across the river, at least what ability should they have. (That is the frog’s longest jump distance).

Input

The input contains several cases. The first line of each case contains three positive integer L, n, and m.
Then n lines follow. Each stands for the distance from the starting banks to the nth stone, two stone appear in one place is impossible.

Output

For each case, output a integer standing for the frog’s ability at least they should have.

Sample Input

6 1 2
2
25 3 3
11
2
18

Sample Output

4
11

#define _CRT_SECURE_NO_WARNINGS
#include<stdio.h>
#include<stdlib.h>
int a[500000];
int b[500001];
int l, n, m;
int cmp(const void *a, const void *b)
{
	return *(int*)a - *(int*)b;
}
int check(int mid)
{
	int sum = 0, num = 1;
	for (int i = 0; i <= n; i++)
	{
		if (sum + b[i] <= mid)
			sum += b[i];
		else
			sum = b[i], num++;
	}
	if (num <= m)
		return 1;
	else
		return 0;
}
int binary(int left,int right)
{
	while (left < right)
	{
		int mid = (left + right) >> 1;
		if (check(mid))
			right = mid;
		else
			left = mid + 1;
	}
	return left;
}
int main()
{
	while (~scanf("%d%d%d", &l, &n, &m))
	{
		for (int i = 0; i < n; i++)
			scanf("%d", &a[i]);
		qsort(a, n, sizeof(a[0]), cmp);
		b[0] = a[0];
		for (int i = 1; i < n; i++)
			b[i] = a[i] - a[i - 1];
		b[n] = l - a[n - 1];
		int right = l;
		int left = 0;
		for (int i = 0; i <= n; i++)
		{
			if (b[i] > left)
				left = b[i];
		}
		printf("%d\n", binary(left, right));
	}
}

猜你喜欢

转载自blog.csdn.net/WxqHUT/article/details/85393247