分治算法(一)

基本思想:

当我们求解某些问题时,由于这些问题要处理的数据相当多,或求解过程相当复杂,使得直接求解法在时间上相当长,或者根本无法直接求出。对于这类问题,我们往往先把它分解成几个子问题,找到求出这几个子问题的解法后,再找到合适的方法,把它们组合成求整个问题的解法。如果这些子问题还较大,难以解决,可以再把它们分成几个更小的子问题,以此类推,直至可以直接求出解为止。这就是分治策略的基本思想。

解题步骤:

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

(2)求解,当子问题划分得足够小时,用较简单的方法解决;
(3)合并,按原问题的要求,将子问题的解逐层合并构成原问题的解。
 

应用:

1)二分法:利用分治策略求解时,所需时间取决于分解后子问题的个数、子问题的规模大小等因素,而二分法,由于其划分的简单均匀的特点,是经常采用的一种有效的方法,例如二分法检索。

二分法搜索C参考代码:

#include <iostream>
#include <stdio.h>
using namespace std;
bool erfen(int a[],int low,int high,int x);
int main()
{
    int a[100];
    int N,x;
    scanf("%d",&N);//数组大小,3
    for(int i=0;i<N;i++){
        scanf("%d",&a[i]);
    }//输入为1,2,3
    scanf("%d",&x);//要找的数,3
    if(erfen(a,0,N-1,x)){
        printf("能找到%d\n",x);
    }
    else{
        printf("没有这个数。\n");
    }
    return 0;
}
bool erfen(int a[],int low,int high,int x){
int mid;
while(low<=high){
    mid=(low+high)/2;
    if(x>a[mid]){
        low=mid+1;
    }
    else if(x<a[mid]){
        high=mid-1;
    }
    else if(x==a[mid]){
        return true;
    }
}
return false;
}

 2)找出伪币:

    给你一个装有1 6个硬币的袋子。1 6个硬币中有一个是伪造的,并且那个伪造的硬币比真的硬币要轻一些。你的任务是找出这个伪造的硬币。为了帮助你完成这一任务,将提供一台可用来比较两组硬币重量的仪器,利用这台仪器,可以知道两组硬币的重量是否相同。比较硬币1与硬币2的重量。假如硬币1比硬币2轻,则硬币1是伪造的;假如硬币2比硬币1轻,则硬币2是伪造的。这样就完成了任务。假如两硬币重量相等,则比较硬币3和硬币4。同样,假如有一个硬币轻一些,则寻找伪币的任务完成。假如两硬币重量相等,则继续比较硬币5和硬币6。

    如果像上面说的一样,两个硬币两个硬币地比的话,最坏的情况要比8次。如果用分治的思想来解决会好一些,先把16个硬币分成A组8个的硬币,B组8个硬币,即将问题划分成规模小的同类问题;如果A组轻,则伪币在A组里,则将A组分成A1组4个B1组四个,如果A1组轻,则将A1组分成A2组两个和B2组两个,如果A2组轻,则称A2组的两个硬币就能得到假币,即子问题已经足够小,可以轻易的解决问题;前面写的几个如果,即子问题解,逐层合并就得到了问题的解。比了四次就得到了解,显然比两个两个的比硬币好的多。

3)棋牌覆盖

这位博主写的挺好,图很形象! 

http://blog.csdn.net/acm_jl/article/details/50938164

 4)归并排序和快速排序见分治算法(二)

posted @ 2017-07-25 20:34  路人姜。  阅读(270)  评论(0编辑  收藏  举报