当前位置: 首页 > article >正文

分治法的适用条件及基本步骤,快速幂算法

分治法所能解决的问题一般具有一下几个特征

*该问题的规模缩小到一定程度就可以容易的解决

*该问题可以分解为若干个规模较小的问题

*利用该问题分解的子问题的解可以合并为该问题的解

*该问题所分解出的各个子问题是相互独立的

divide-and-conquer(P){

        if(|p| <= n0)  adhoc(P); 解决小规模的问题

        divide P into smaller subinstances P1,P2,....Pk  //分解问题

        for (i=1,i<=k,i++)

          yi=divide-and-conquer(Pi); //递归的解的各个子问题

        return merge(y1,......yk); //各子问题的解合并为原问题的解

复杂性分析:

分治法将规模为n的问题分成k个规模为n/m的子问题去解

(1)设分解阈值n=1且adhoc解规模为1的问题耗费1个单位时间

(2)设将原问题分解为k个子问题以及用merge将k个子问题的解合并为原问题的解需要f(n)个单位时间。

(3)用T(n)表示分治法解规模为|P|=n的为题所需的计算时间

T(n) =  O(1)                     n=1

T(n) = kT(n/m) + f(n)       n>1

二分搜索技术

非递减序的n个元素a[0:n-1],先要在这n个元素中找出一特定的元素x

分析:设在a[l:r]中找x,mid=(l+r)/2

(0)如果x==a[mid],则找到

(1)如果x<a[mid],则继续在a[i,mid-1]中找x即可

(2)如果x>a[mid],则继续在a[mid+1,j]中找x即可

递归算法:

template<class Type> //递归
int BiSearch(Type a[], const Type& x, int l, int r)
{
    if (r > l)
    {
        int m = (l + r) / 2;
        if (x == a[m])
            return m;
        else if (x < a[m])
            return BiSearch(a, x, l, m - 1);
        else
            return BiSearch(a, x, m + 1, r);
    }
    else return -1;
}

非递归算法:

template<class Type> //非递归
int BiSearch(Type a[], const Type& x, int l, int r)
{
    while (r >= l)
    {
        int m = (l + r) / 2;
        if (x == a[m])
            return m;
        if (x < a[m])
            r = m - 1;
        else l = m + 1;
    }
    else return -1;
}

非递归算法复杂度分析:每执行一次while循环,带搜索数组的大小减少1/2,在最坏的情况下,while循环被执行了O(logn)次,因此算法在最坏的情况下的计算时间复杂性为O(logn).

快速幂算法:

给定实数a和非负整数n,用分治法设计求a^n的快速算法(递归算法)

分析:

a^n = 0     a=0

a^n = 1     n=0

a^n = (a^(n/2))^2       n > 0,n为偶数

(a^(n/2)^2 * a          n >  0,n为奇数

double exp2(double a, int n)
{
    if (a == 0)
        return 0;
    if (n <= 0)
        return 1;
    else
    {
        int x = exp2(a, n / 2);
        if (n % 2)
            return a * x * x;
        else
            return x * x;
    }
}

给定正整数a和n,用二分法设计出求a^n的快速算法(非递归算法)

举例求a^93

n=93的二进制表示(如图)

0                1              0                1              1            1           0            1

a^128        a^64        a^32          a^16         a^8        a^4        a^2         a

因此:a^93--------->a^64*a^16*a^8*a^4*a

double exp2(double a, int n)
{
    int i;
    double b, s = 1.0;
    i = n;
    b = a;
    while (i > 0)
    {
        if (i % 2)
            s *= b;
        i /= 2;
        b *= b;
    }
    return s;
}


http://www.kler.cn/a/564126.html

相关文章:

  • 3、.Net UI库:SunnyUI - 开源项目研究文章
  • azure sql 网络安全组 网络安全sql注入
  • 网络安全应急响应中主机历史命令被删除 网络安全事件应急响应
  • 【博资考4】网安学院-硕转博考试内容
  • 【天地图-点线面最全功能】天地图实现功能:回显、绘制、编辑、删除任意点线面
  • Linux 文件操作与 Socket 编程核心知识详解
  • JVM的初步学习
  • Chapter 4 Noise performance of elementary transistor stages
  • windows 下 使用Python OpenCV针对 压缩的tiff 图像进行解压缩 并转换成多张jpeg 图像
  • 部署Flink1.20.1
  • nginx 搭建 IPv6 -> IPv4 反向代理服务器
  • 淘宝商品搜索API实战:Elasticsearch分词与排序算法优化
  • 【数字图像处理三】图像变换与频域处理
  • 矩阵营销的 AI 进化:DeepSeek 如何助力批量运营账号?
  • 使用 Apache Dubbo 释放 DeepSeek R1 的全部潜力
  • Linux nc 命令详解
  • 如何下载MinGW-w64到MATLAB
  • Java集合性能优化面试题
  • 【Linux】CentOS7停服之后配置yum镜像源
  • Ubuntu 下通过 Docker 部署 Nginx 服务器