算法导论学习笔记(三) 初稿

几个小概念
  • 当子问题足够大到需要使用递归求解时,称为递归情况

  • 当子问题足够小到无需递归时,称为基本情况

  • 等式或不等式都可被称为递归式

  • 求解递归的三种方法:代入法,递归树法,主方法

  • 对于等式递归,其结果应为Θ,而不等式为Ω或Ο

  • 对于分治时两部分的向上向下取整,递归式的边界条件等细节时常可以忽略不计

4.1 引例——最大子数组

  1. 暴力求解法

    1. 全为正数:两层循环遍历求最大差值

    2. 有正有负:先变化为全正,再两层循环求最大差值

  2. 分治法

    • 两种情况

      1. 全为正数:化简为正负相间的形式(相邻相减)
      2. 有正有负:无需化简
    • 求解思想——将数组分为三部分:完全在中间以左,完全在中间以右,贯穿左右

    • 具体代码
#include <iostream>
#include <algorithm>
using namespace std;

struct qu{
    int left;
    int right;
    int result;
    qu()
    {
        left=right=0;
        result=0;
    }
    qu(int le, int ri)
    {
        left=le;
        right=ri;
    }

    qu& operator =(const qu& temp)
    {
        left=temp.left;
        right=temp.right;
        result=temp.result;
        return *this;
    }

};
qu maxcross(int *a, int l, int m, int r)
{
    int i,j;
    int maxi=a[m], maxj=a[m+1];
    int resulti=m,resultj=m+1;
    int temp1=maxi,temp2=maxj;

    for(i=m-1; i>=l; i--){
        temp1+=a[i];
        if(temp1>maxi){
            maxi=temp1;
            resulti=i;
        }
    }
    for(j=m+2; j<=r; j++){
        temp2+=a[j];
        if(temp2>maxj){
            maxj=temp2;
            resultj=j;
        }
    }

    qu Q(resulti,resultj);
    Q.result=maxi+maxj;
    return Q;
}

qu maxsub(int *a, int l, int r)
{
    if(l>=r){
        qu temp(l,l);
        temp.result=a[l];
        return temp;
    }
    int m=(l+r)/2;
    qu Q[3];
    Q[0]=maxsub(a,l,m);
    Q[1]=maxsub(a,m+1,r);
    Q[2]=maxcross(a,l,m,r);

    qu maxq;
    maxq=Q[0];
    if(Q[1].result>maxq.result)
        maxq=Q[1];
    if(Q[2].result>maxq.result)
        maxq=Q[2];
    return maxq;
} 

int main(){
    int a[16]={13,-3,-25,20,-3,-16,-23,18,20,
    -7,12,-5,-22,15,-4,7};
    qu re;

    re=maxsub(a,0,15);
    cout<<re.left<<" "<<re.right<<endl;
    cout<<re.result<<endl;
    return 0;
}

4.2 矩阵乘法

  1. 正常算法(Θ(n^3^))

    • 普通拆分
    • 递归拆分(以下标实现拆分)
  2. Strassen方法

    • 步骤概述:
      • 分解矩阵:采用下标计算法分解为n/2*n/2的子矩阵
      • 创建 S1,...,S10 10个n/2*n/2的子矩阵,并赋值
      • 递归计算7个矩阵的积 P1,...,P7
      • 通过 Pi 的不同组合计算结果
    • 矩阵S
      S1=B12B22

      S2=A11+A12

      S3=A21+A22

      S4=B21B11

      S5=A11+A22

      S6=B11+B22

      S7=A12A22

      S8=B21+B22

      S9=A11A21

      S10=B11+B12
    • 递归相乘
      P1=A11S1

      P2=S2B22

      P3=S3B11

      P4=A22S4

      P5=S5S6

      P6=S7S8

      P7=S9S10
    • 最后的加减法运算

C11=P5+P4P2+P6

C12=P1+P2

C21=P3+P4

C22=P5+P1P3P7

4.3 朴素的代入法(数学归纳法)

运用数学归纳法的基本知识,同时兼顾渐进符号所省略的较小项。

4.4 本质的递归树法(结构分析)

主要目的是生成一个好的猜想,通常不会十分精确

包括:

  • 忽略舍入
  • 忽略节点的缺失,即假设为完全树

4.5 定理性的主方法(性质使用)

  1. 内容

    • 对于形如 T(n)=aT(n/b)+f(n) 的递推式

      • 如果存在某常数ε>0,有 f(n)=O(nlogbaϵ) ,则 T(n)=Θ(nlogba)

      • 如果 f(n)=Θ(nlogba) ,则 T(n)=Θ(nlogbalgn)

      • 如果存在某常数ε>0,有 f(n)=Ω(nlogb)

      • 如果 f(n)=Θ(nlogba lgkn) ,那么 T(n)=Θ(nlogba lgk+1n)
    • 缺陷 ——f(n)必须与 nlogba nϵ 的差距,因此存在“间隙”

  2. 缺陷举例
    T(n)=2T(n/2)+nlgn

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值