(3.12)递归与分支之分治

2024-06-08 06:38
文章标签 递归 分治 分支 3.12

本文主要是介绍(3.12)递归与分支之分治,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

文章目录

    • 1.算法的总体思想
    • 2.分治法的适用条件
    • 3.递归复杂度计算

1.算法的总体思想

  • 分治和递归是互不分离的
  • (1)将要求解的较大规模的问题分割成k个更小规模的子问题
  • (2)对这k个子问题分别求解。如果子问题的规模仍然不够小,则再划分为k个子问题,如此递归的进行下去,直到问题规模足够小,很容易求出其解为止。
    在这里插入图片描述
  • (3)将求出的小规模的问题的解合并为一个更大规模的问题的解,自底向上逐步求出原来问题的解
    在这里插入图片描述
  • 总结,算法的总体思想是:将求出的小规模的问题的解合并为一个更大规模的问题的解,自底向上逐步求出原来问题的解。

2.分治法的适用条件

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

  • (1)该问题的规模缩小到一定的程度就可以容易地解决;
    因为问题的计算复杂性一般是随着问题规模的增加而增加,因此大部分问题满足这个特征。

  • (2)该问题可以分解为若干个规模较小的相同问题,即该问题具有最优子结构性质
    这条特征是应用分治法的前提,它也是大多数问题可以满足的,此特征反映了递归思想的应用

  • (3)利用该问题分解出的子问题的解可以合并为该问题的解;
    能否利用分治法完全取决于问题是否具有这条特征,如果具备了前两条特征,而不具备第三条特征,则可以考虑贪心算法或动态规划。

  • (4)该问题所分解出的各个子问题是相互独立的,即子问题之间不包含公共的子问题。
    这条特征涉及到分治法的效率,如果各子问题是不独立的,则分治法要做许多不必要的工作,重复地解公共的子问题,此时虽然也可用分治法,但一般用动态规划较好。

  • 分治法的基本步骤

divide-and-conquer(P)
{if ( | P | <= n0) adhoc(P); //解决小规模的问题,问题规模P很小,就直接求解divide P into smaller subinstances P1,P2,...,Pk; //分解问题,分解成k个子问题for (i=1,i<=k,i++)yi=divide-and-conquer(Pi); //递归的解各子问题,第i个问题的解在yi中return merge(y1,...,yk); //将各子问题的解合并为原问题的解
}
  • 平衡子问题
    使用分治递归,最好使子问题的规模大致相同
  • 分治法的复杂性分析
    设问题规模足够小的adhoc耗费1个单位时间。
    设分解子问题及子问题的解合并需用f(n)个单位时间。
    用T(n)表示该分治法解规模为|P|=n的问题所需的计算时间,则有:
    在这里插入图片描述

3.递归复杂度计算

  • 目前的组要方法:代换法,递归树法,主方法

  • 求解复杂度需要忽略技术细节:在进行分析时先忽略这些细节,而后再确定其重要与否
    (1)假设n 可能是非整数.
    (2)忽略掉上取整和下取整,即n/2 可能是非整数.
    (3)忽略掉边界条件:
    在这里插入图片描述
    在这里插入图片描述

  • (1)代换法
    主要思想:1、猜测解的形式;2、 通过数学归纳法找出使解真正有效的常数.
    eg:
    归并排序计算复杂度的递推关系式为:T(n)=2T(n/2)+n
    步骤1:猜测 T(n)=O(n lgn)。原因:问题的规模分成n/2,合并的规模是n,每次分成一半的规模,分的是2个,这样分下去最多分logn趟,每趟最多处理n个数据,所以是O(nlong)的复杂度
    步骤2:证明对某一常数c>0,有 T(n)≤cnlgn
    在这里插入图片描述
    结论: 代换法名称来源于当归纳假设用较小的值时,用所猜测的值代替函数的解。这种方法很有效,但只能用于解的形式很容易猜测的情形

  • (3)主方法
    T(n) = aT(n/b) + f(n)
    在这里插入图片描述
    eg1:T(n)=9T(n/3)+n求出其四件复杂度
    在这里插入图片描述
    eg2:求解: T(n)=T(2n/3)+1的时间复杂度
    在这里插入图片描述

这篇关于(3.12)递归与分支之分治的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/1041435

相关文章

C语言函数递归实际应用举例详解

《C语言函数递归实际应用举例详解》程序调用自身的编程技巧称为递归,递归做为一种算法在程序设计语言中广泛应用,:本文主要介绍C语言函数递归实际应用举例的相关资料,文中通过代码介绍的非常详细,需要的朋... 目录前言一、递归的概念与思想二、递归的限制条件 三、递归的实际应用举例(一)求 n 的阶乘(二)顺序打印

Jackson库进行JSON 序列化时遇到了无限递归(Infinite Recursion)的问题及解决方案

《Jackson库进行JSON序列化时遇到了无限递归(InfiniteRecursion)的问题及解决方案》使用Jackson库进行JSON序列化时遇到了无限递归(InfiniteRecursi... 目录解决方案‌1. 使用 @jsonIgnore 忽略一个方向的引用2. 使用 @JsonManagedR

Rust中的BoxT之堆上的数据与递归类型详解

《Rust中的BoxT之堆上的数据与递归类型详解》本文介绍了Rust中的BoxT类型,包括其在堆与栈之间的内存分配,性能优势,以及如何利用BoxT来实现递归类型和处理大小未知类型,通过BoxT,Rus... 目录1. Box<T> 的基础知识1.1 堆与栈的分工1.2 性能优势2.1 递归类型的问题2.2

Git中恢复已删除分支的几种方法

《Git中恢复已删除分支的几种方法》:本文主要介绍在Git中恢复已删除分支的几种方法,包括查找提交记录、恢复分支、推送恢复的分支等步骤,文中通过代码介绍的非常详细,需要的朋友可以参考下... 目录1. 恢复本地删除的分支场景方法2. 恢复远程删除的分支场景方法3. 恢复未推送的本地删除分支场景方法4. 恢复

Codeforces Round #240 (Div. 2) E分治算法探究1

Codeforces Round #240 (Div. 2) E  http://codeforces.com/contest/415/problem/E 2^n个数,每次操作将其分成2^q份,对于每一份内部的数进行翻转(逆序),每次操作完后输出操作后新序列的逆序对数。 图一:  划分子问题。 图二: 分而治之,=>  合并 。 图三: 回溯:

PHP实现二叉树遍历(非递归方式,栈模拟实现)

二叉树定义是这样的:一棵非空的二叉树由根结点及左、右子树这三个基本部分组成,根据节点的访问位置不同有三种遍历方式: ① NLR:前序遍历(PreorderTraversal亦称(先序遍历)) ——访问结点的操作发生在遍历其左右子树之前。 ② LNR:中序遍历(InorderTraversal) ——访问结点的操作发生在遍历其左右子树之中(间)。 ③ LRN:后序遍历(PostorderT

oracle11.2g递归查询(树形结构查询)

转自: 一 二 简单语法介绍 一、树型表结构:节点ID 上级ID 节点名称二、公式: select 节点ID,节点名称,levelfrom 表connect by prior 节点ID=上级节点IDstart with 上级节点ID=节点值 oracle官网解说 开发人员:SQL 递归: 在 Oracle Database 11g 第 2 版中查询层次结构数据的快速

Leetcode面试经典150题-128.最长连续序列-递归版本另解

之前写过一篇这个题的,但是可能代码比较复杂,这回来个简洁版的,这个是递归版本 可以看看之前的版本,两个版本面试用哪个都保过 解法都在代码里,不懂就留言或者私信 class Solution {/**对于之前的解法,我现在提供一共更优的解,但是这种可能会比较难懂一些(思想方面)代码其实是很简洁的,总体思想如下:不需要排序直接把所有数放入map,map的key是当前数字,value是当前数开始的

【UVA】10651-Pebble Solitaire(直接递归或者记忆化)

不知道这个题UVA的数据是怎么的,用2个方法交了,第一次直接递归,第二次记忆化剪枝,时间竟然一样!? 直接郁闷了,简单的二进制表示状态和二进制运算。 14145176 10651 Pebble Solitaire Accepted C++ 0.009 2014-09-04 09:18:21 #include<cstdio>#include<algorithm>#inclu