python算法思维笔记(2)

本文介绍了分治策略的基础概念,包括最优化问题、分治的三个步骤(分解、解决、合并)。以数字三角形问题为例,阐述如何使用递归和分治思想解决最优化问题,分析了递归的实现和时间复杂度。同时,文章还讨论了汉诺塔问题的分治解法,并提到了最大子序列和问题的分治解决方案。
摘要由CSDN通过智能技术生成

分治的基本概念

在右边的数字三角形中寻找一条从顶部到底边的路径,使得路径上所经过的数字之和最大,路径上的每一步都只能往左下或右下走,只需求出最大的和,不需要给出具体路径。
对于n层的数字,一共有2n-1条不同的路径。
直接用循环来求出每条路径的和是非常困难的,这里我们用分治策略来解决这个问题。
在这里插入图片描述

最优化问题与最优解

数字三角形问题是个典型的最优化问题。
最优化问题指的是,问题可以有多个解,每个解有一个值,我们希望找到最优的那个值,称为一个最优解(最优解可能有多个)
数字三角形问题中,从上往下有很多不同的路径,这些不同的路径就是不同的解,其中路径上的数字和最大的解,就是我们要寻找的最优解

分治=分解+解决+合并

分治策略的核心是:

  1. 将大的问题分解为形式相同的更小的子问题,子问题继续分解为更小的子问题… 一直分解下去,直到问题小到可以直接求解(自顶向下分解
  2. 直接解决最小的问题
  3. 最小问题求解后的结果依次进行合并,解决较大的问题,一直进行下去,直到解决原问题(自底向上合并)

(二分法也是一种分治,是一种尽量将问题分为规模相同的2个子问题的分治)

分解

以7为顶点(顶点为第0行第0列)的三角形问题,记为f(0,0)),可分解成2个较小的问题:

  1. 以3为顶点(顶点为第1行第0列)的问题,记为f(1,0)
  2. 以8为顶点(顶点为第1行第1列)的问题,记为f(1,1)

可知, f(0,0) = 7 + max(f(1,0), f(1,1) ),这是个分解动作,即:一个三角形问题=该问题顶点的数字+下面两个子问题的解的较大者

f(1,0)和f(1,1)如何求解?当然是继续分解
f(1,0) = 3+max( f(2,0), f(2,1) )
f(1,1) = 8+max( f(2,1), f(2,2) )

因此f(0,0) = 7+max( 3+max( f(2,0), f(2,1) ), 8+max( f(2,1), f(2,2) ) )
一直分解下去,直到f(4,x),x为列号;由于是最后一层,可知f(4,x)=A[4][x]

解决

层数大于等于2的问题都无法直接求出结果,需要继续分解,直到层数为1
考察原问题左下角的层数为2的问题的分解
f(3,0)=2+max(f(4,0), f(4,1))=2+max(A[4][0],A[4][1])= 2+5 = 7

合并

最小子问题求解之后,根据规则组合成上一层的子问题的解,一直进行下去,可以将原问题的解求出。

右上角的小数字表示以大数字为顶点的子问题的解,都是用大数字加上左下角的小数字和右下角小数字中的较大者,例如:
f(0,0)=7+max(f(1,0),f(1,1))=7+max(23,21)=30
在这里插入图片描述

用递归实现分治

什么是递归

有两种实现分治的方法:递归(自顶向下)、递推(自底向上)

什么是递归
函数调用自身的操作

def Factorial(n):
    if n==1:return 1  #最小子问题,递归的出口
    else: return n*Factorial(n-1) #递归调用
print(Factorial(10))

一定要为递归函数设计出口,否则会陷入死循环,最后会导致栈溢出

阶乘问题

分治策略完成n的阶乘。

  1. 分解方法:n! = n * (n-1)!
  2. 统一表达式:f(i) 是i的阶乘
  3. 最小子问题:f(1) = 1

递归函数表达分治策略:
f(n) = n*f(n-1)
f(1) = 1

分治是思想,递归是实现分治的手段之一

掌握正确的问题拆解方法: n! = n * (n-1)! --> f(n) = n*f(n-1)
掌握用函数统一表达子问题的方法:f(i) 是i的阶乘
为原问题定义最小子问题:f(1) = 1

用递归解决三角形问题

设计数据结构来存储三角形数据,最简单直观的方式,是使用嵌套的列表

A = [ [7], [3,8], [8,1,0], [2,7,4,4], [4,5,2,6,5] ]

对A中任一数字A[i][j],其左下角的数为A[i+1][j],右下角的数为A[i+1][j+1]
用正确的函数来统一描述原问题和子

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

勤奋努力的野指针

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值