• 分治思想


    分支策略的基本思想:

    第一步:将原始问题划分(分成两个或几个不同的部分或步骤)或者归结(归纳总结出普遍适用的解法)为规模较小的子问题

    第二步:递归或迭代(iterative) 

    *迭代(递推+倒推):

    确定变量

    在可以用迭代算法解决的问题中,至少存在一个直接或间接地不断由旧值递推出新值的变量,这个变量就是迭代变量。

    建立关系式

    所谓迭代关系式,指如何从变量的前一个值推出其下一个值的公式(或关系)。迭代关系式的建立是解决迭代问题的关键,通常可以使用递推倒推的方法来完成。

    过程控制

    在什么时候结束迭代过程?这是编写迭代程序必须考虑的问题。不能让迭代过程无休止地重复执行下去。

    第三步:将子问题的解综合得到原问题的解

    三注意:

    1. 子问题与原始问题性质完全一样:递归基础
    2. 子问题之间可彼此独立的求解:不受其他子问题干扰
    3. 递归停止时子问题可以直接求解:子问题足够小
     

    分支策略的典型例子:

    1. 二分查找

    中心思想:通过x与中位数的比较,将原问题归结为规模为n/2的子问题

    递归法:

    int binary_search(int l, int r, int x){
        if(l == r) return 0;
        int m=(l+r)/2;
        if(a[m] == x) return m;
        else if(a[m] > x)binary_search(l,m,x);
        else if(a[m] < x)binary_search(m+1,r,x);
    }
    int main(){
        ...
        binary_search(1,n,x);
        ...
    }

    递推法:

    l=1;
    r=n;
    while(l<=r){
        m=(l+r)/2;
        if(a[m]==x){
            printf("%d",m);
            break;
        }
        else if(T[m]>x)r=m-1;
        else l=m+1;
    }

    二分查找最坏情况下时间复杂度:

    W(n) = W(n/2) + 1 

    W(1) = 1

    可以解出:

    W(n) = log(n) + 1

    2. 归并排序

    中心思想:将原问题归结为规模为n/2的2个子问题

    来源:http://open.163.com/movie/2010/3/D/8/M6U6LS8CV_M6U6NS2D8.html(哈佛CS50公开课)

    On input of n elements:

      if n < 2

        Return.

      else:

        Sort left halfof elements.

        Sort right half of elements.

        Merge sorted halves.

    /*
    做实事的merge 算法中心
    "Conquer"
    */ void merge(int l, int m, int r){ int i=l,j=m+1; int k=l; while(i<=m && j<=r){ if(a[i]<a[j])tmp[k++]=a[i++]; else tmp[k++]=a[j++]; } while(i<=m)tmp[k++]=a[i++]; while(j<=r)tmp[k++]=a[j++]; //not j<=n!!! for(i=l;i<=r;i++) a[i]=tmp[i]; } /* 并未做实事
    "Divide"
    */ void merge_sort(int l, int r){ if(l == r) return; int m=(l+r)/2; merge_sort(l,m); merge_sort(m+1,r); merge(l,m,r); } int main(){ ... merge_sort(1,n); ... }

    归并排序最坏情况下时间复杂度:

    W(n) = 2W(n/2) + n-1

    W(1) = 0

    可以解出:

    W(n) = nlog(n) - n + 1

    3. 汉诺塔问题

    中心思想: 将原问题归结为规模为n-1的2个子问题i.e. 从A到B和从B到C

    伪代码:

    来源:https://class.coursera.org/algorithms-001/lecture/47 (北京大学算法设计与分析公开课)

    Hanoi(A, C, n) //n个盘A到C

    if(n=1) then move(A, C) //1个盘A到C

    else Hanoi(A, B, n-1)

           move(A,C)

           Hanoi(B, C, n-1)

  • 相关阅读:
    利用兼容DC和兼容位图实现图形重绘
    MFC实现文件打开和保存功能实现
    CFile文件操作示例
    利用互斥对象实现线程同步的实例说明
    bootstrap3 input 验证样式【转】
    js event 冒泡和捕获事件详细介绍【转】
    Html+Ajax+Springmvc+Mybatis,不用JSP【转】
    hp电脑重装win7 64位 后 所有软件都装不上问题【转】
    bootstrap 模态 modal 小例子【转】
    servlet 获取 post body 体用流读取为空的问题【转】
  • 原文地址:https://www.cnblogs.com/peccavi/p/4988892.html
Copyright © 2020-2023  润新知