分治算法

一、概述

分治算法说白了就是把一个大型问题转化为小问题逐个解决。

个人感觉和分治算法含有递归的意味。

一般步骤:

(1)分解,将要解决的问题划分成若干规模较小的同类问题;

(2)求解,当子问题划分得足够小时,用较简单的方法解决;

(3)合并,按原问题的要求,将子问题的解逐层合并构成原问题的解。

总之,分治可以产生贪心,二分,线段树等问题。

说实话,分治算法是一种思想,没有什么特定的代码框架。

接下来我们来看一些使用分治算法的经典问题。

二、二分找数

二分是一种求极值的算法,通常已知答案的取值范围,枚举范围中点,并逐步缩小范围。

举个例子:员工小C和志熊在一起快乐吃鸡,两人决赛圈想当伏地魔而不专心,玩起了猜子弹游戏。

当然,小C是个新手,而系统自动拾取子弹,所以自己从来不关心自己有多少子弹(只是看有拾取标识就点);志熊是个黄金,知道系统认为同一种捡200发就够了,那志熊每一次猜测的最优解是什么呢?

自然是先猜(1+200)/2=100发了,这样有可能一次猜中(几率很小,欧吃矛),但更多的好处在于可以立刻缩减最非时的最大范围。于是这样每次猜正中间,很快便能找到答案,而且思维比较规范,不会乱。

这就是分治算法的体现。

代码主要结构如下,各有各的写法:

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

三、快排 

已经厌倦 algorithm 中的sort的OIER以及与时间赛跑的dalao可以试试手打快排。

快排是当前对于部分问题来说,确实是所有排序方法中最优解之一。

代码贴一下吧:

void qsort(int l,int r)
{
	int i,j,mid,p;
	i=l;j=r;
	mid=a[(l+r)/2];
	do
	{
		while (a[i]<mid) i++;
		while (a[j]>mid) j--;
		if (o<=j)
		{
			p=a[i];a[i]=a[j];a[j]=p;
			i++;j--;
		}
	}while(i<=j);
	if (l<j) qsort(l,j);
	if (i<r) qsort(i,r);
}

 

四、总结

这个思想比较巧妙,大家可以写一些这几道题,比较有趣,分治思想也比较明显。

[HNOI2006]鬼谷子的钱袋

洛谷 P1010 幂次方

洛谷 P1908 逆序对

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值