分治算法

一.基本思想:

▪ 将原始问题划分或者归结为规模较小的子问题。
▪递归或迭代求解每个子问题。
▪将子问题的解综合得到原问题的解。

注意: 1.子问题与原始问题性质完全一样。
    2.子问题之间可彼此独立地求解。
    3.递归停止时子问题可直接求解。

 

二.应用

1.Hanoid塔问题
  设a,b,c是3个塔座。开始时,在塔座a上有一叠共n个圆盘,这些圆盘自下而上,由大到小地叠在一起。各圆盘从小到大编号为1,2,…,n,现要求将塔座a上的这一叠圆盘移到塔座c上,并仍按同样顺序叠置,移动过程中不出现大圆盘在小圆盘上面的情况。

#include 

void Hanoi(int n,char a,char b,char c)
{
     
    if(n == 1)  //如果只有一个圆盘,直接从a移动到c上
        printf("%c --> %c\n",a,c);
    else
    {
     
        Hanoi(n-1,a,c,b);  //先将上面的n-1个圆盘从a借助c移动到b上
        printf("%c --> %c\n",a,c);  //将剩下的最后一个从a移动到c上
        Hanoi(n-1,b,a,c);  //对剩下的n-1个圆盘再调用该算法,从b借助a移动到c上
    }
}

int main()
{
     
    int n;
    char a='A',b='B',c='C';
    scanf("%d",&n);  //接收要移动的圆盘个数
    Hanoi(n,a,b,c);

    return 0;
}

2.芯片测试
  n片芯片,其中好芯片至少比坏芯片多一片。现在需要通过测试从中找出一片好芯片,测试的方法是:将2片芯片放到测试台上,2片芯片互相测试并报告测试结果:好或坏。假定好芯片的报告是正确的,坏芯片的报告是不可靠的(可能是对的,可能是错的)。请设计一种测试方法,使用最少的测试次数从中挑出一片好芯片。
思路:
▪ 分治算法:n为偶数时,将n片芯片两两一组做测试淘汰,剩下的芯片构成子问题,进入下一轮分组淘汰;n为奇数时,由于可能出现好坏芯片数量相等的情况,故增加一轮特殊处理:把这个轮空芯片与其他每片芯片都测一遍,如果它是好的,算法结束,如果它是坏的,丢弃它。
▪ 淘汰规则:测试结构都为好时,任留一片,进入下轮;否则全抛弃。(测试结果都为好时,两片芯片都好或都坏;其余情况至少1片是坏的)
▪ 递归截止条件:n<=3.当有3片芯片,1次测试可得到好芯片;1片或2片芯片,不再需要测试,都为好芯片。

算法 Test(n)
while n >3 do
将芯片分成n/2// 轮空处理
for  i=1 to n/2  do
    if  2片好  then   则任取1片留下
    else  2片 同时丢掉
n=剩下的芯片数
if n =3 then
    任取2片芯片测试
    If  11坏  then  取没测的芯片
else	任取1片被测芯片
      if n =2 or 1  then 任取1

其他的一些应用:幂乘问题

 

三.改进分治算法的途径

1.减少子问题数
  利用子问题依赖关系,用某些子问题解的代数表达式表示另一些子问题的解,减少独立计算子问题个数。(可以理解成变换表达式,减少子问题个数)
  如矩阵相乘问题中的Strassen矩阵乘法、整数位乘问题。
2.增加预处理
  如果每个子问题都要进行某种操作,则可以将这种操作在划分子问题前完成。
  如解决平面点对问题算法的改进。

 

四.典型的分治算法

1.检索算法:
 ▪ 二分检索
2.排序算法:
 ▪ 快速排序、二分归并排序
3.选择算法(一般选择问题的一个应用:管道位置问题)
 ▪ 选最大与最小
  算法一:顺序比较
  算法二:分组算法:两两比较,所有大的划在一组,所有小的划在一组。
  算法三:分治算法:将数组从中间划分为两个子数组,递归地在两个子数组中求最大,最小,最后将两组最值比较,得到总数组的最值。
 ▪ 选第k小
  如求第二小时,可用锦标赛算法
 ▪ 选最大
4.快速傅里叶变换FFT算法(应用:信号平滑处理)
5.计算平面点集的凸包

你可能感兴趣的:(算法训练集,分治算法,汉诺塔问题,芯片问题)