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

动态规划:青蛙跳台阶实践

一只青蛙要跳上有 n 级的台阶,每次只能跳 1 级或 2 级台阶,问青蛙总共有多少种不同的跳法?

暴力递归算法

我们按照最后一步是跳1阶还是跳2阶,将所有的方案划分成不重不漏的两个集合S(n−1)S(n-1)S(n1)S(n−2)S(n-2)S(n2),两个集合方案数之和就是n阶的方案数。

子集合 S(n−1)S(n-1)S(n1)(最后一步跳 1 级):跳到第 5 级前,已先到第 4 级,对应 “跳到第 4 级的所有跳法”:

  • 1->2->3->4->5(最后 1 级:4→5)
  • 1->2->4->5(最后 1 级:4→5)
  • 1->3->4->5(最后 1 级:4→5)
  • 2->3->4->5(最后 1 级:4→5)
  • 2->4->5(最后 1 级:4→5)

子集合 S(n−2)S(n-2)S(n2)(最后一步跳 2 级):跳到第 5 级前,已先到第 3 级,对应 “跳到第 3 级的所有跳法”:

  • 1->2->3->5(最后 2 级:3→5)
  • 1->3->5(最后 2 级:3→5)
  • 2->3->5(最后 2 级:3→5)

这个问题我们要求出方案数,而非具体的方案,因此有
∣S(n)∣=∣S(n−1)∣+∣S(n−2)∣ |S(n)| = |S(n-1)| + |S(n-2)| S(n)=S(n1)+S(n2)
简单而言
f(n)=f(n−1)+f(n−2) f(n) = f(n-1) + f(n-2) f(n)=f(n1)+f(n2)

代码写起来也非常的简单

def f(n):if n == 1:return 1if n == 2:return 2return f(n-1) + f(n-2)
f(6)
f(5)
f(4)
f(4)
f(3)
f(3)
f(2)=2
f(3)
f(2)=2
f(2)=2
f(1)=1
f(2)=2
f(1)=1
f(2)=2
f(1)=1

在思考这个递归树的时候,有两种思路,一种就是f(n)表示的是所有的方案,f(n-1)是跳的n-1阶的所有方案,f(n-2)是跳到n-2阶的所有方案。另一种呢就是直接表示方案数,但是对我而言,这种比较难以理解,这种理解更偏向于数学抽象。

打印所有的方案

def f(n):"""生成青蛙跳上n级台阶的所有「台阶编号路径」每个路径是一个列表,包含依次经过的台阶编号(最终到达n)例如n=2时,返回[[1,2], [2]],对应路径0→1→2和0→2"""# 边界情况:0级台阶,无需跳跃,路径为空if n == 0:return [[]]# n=1:只有一种路径:0→1if n == 1:return [[1]]# n=2:两种路径:0→1→2 或 0→2if n == 2:return [[1, 2], [2]]res = []# 1. 从n-1级跳1级到n:所有到达n-1的路径后加narr1 = f(n-1)for path in arr1:res.append(path + [n])# 2. 从n-2级跳2级到n:所有到达n-2的路径后加narr2 = f(n-2)for path in arr2:res.append(path + [n])return res# 测试n=5
print("n=5的台阶编号路径:")
for i, path in enumerate(f(5), 1):print(f"方案{i}{path}")

当然也可以直接打印

def print_frog_paths(n, current_path=None):"""直接打印青蛙跳上n级台阶的所有路径(台阶编号)参数:n: 目标台阶数current_path: 当前已走过的路径(用于递归传递)"""# 初始化当前路径if current_path is None:current_path = []# 递归终止条件:已到达目标台阶if n == 0:# 打印当前完整路径print("→".join(map(str, current_path)))return# 情况1:最后一步跳1级(如果可能)if n >= 1:print_frog_paths(n - 1, [n] + current_path )# 情况2:最后一步跳2级(如果可能)if n >= 2:print_frog_paths(n - 2, [n] + current_path)def main():try:n = int(input("请输入台阶的级数:"))if n < 0:print("台阶级数不能为负数!")elif n == 0:print("0级台阶无需跳跃!")else:print(f"青蛙跳上{str(n)}级台阶的所有路径:")print_frog_paths(n)except ValueError:print("请输入有效的整数!")if __name__ == "__main__":main()
frog_paths(5)
frog_paths(4, [5])
frog_paths(3, [5])
frog_paths(3, [4, 5])
frog_paths(2, [4, 5])
frog_paths(2, [3, 5])
frog_paths(1, [3, 5])
frog_paths(2, [3, 4, 5])
frog_paths(1, [3, 4, 5])
frog_paths(1, [2, 4, 5])
frog_paths(0, [2, 4, 5])
frog_paths(1, [2, 3, 5])
frog_paths(0, [2, 3, 5])
frog_paths(0, [1, 3, 5])
frog_paths(1, [2, 3, 4, 5])
frog_paths(0, [2, 3, 4, 5])
frog_paths(0, [1, 3, 4, 5])
frog_paths(0, [1, 2, 4, 5])
frog_paths(0, [1, 2, 3, 5])
frog_paths(0, [1, 2, 3, 4, 5])
http://www.dtcms.com/a/354093.html

相关文章:

  • H20 性能表现之 Kimi-K2
  • 【git】:gitee项目管理vs2019
  • 装饰器进阶与设计模式
  • Linux入门教程 第十五章 Linux 系统调优工具
  • 【工具篇】github/huggingface 镜像源总结
  • 嵌入式系统学习Day24(线程)
  • Custom SRP - Shadow Masks
  • Axure:如何将SVG转换为形状
  • leetcode 155 官方golang标准答案错误
  • Java Lambda 处理日期时间 根据区间找出区间内集合
  • Linux程序与进程:核心概念与管理全解析
  • Class45循环神经网络RNN
  • “互联网 +”时代下开源 AI 大模型 AI 智能名片 S2B2C 商城小程序:行业变革与未来展望
  • 基于 Ultralytics YOLO11与 TrackZone 的驱动的高效区域目标跟踪方案实践
  • Python Imaging Library (PIL) 全面指南:PIL基础入门-Python图像处理实战
  • 多版本兼容的golang客服系统
  • 稀土:从“稀有”到“命脉”的科技核心
  • 通过概率正 - 未标记网络从医学图像的特定感兴趣区域中学习|文献速递-深度学习人工智能医疗图像
  • 【底层机制】thread_local 变量的初始化时机和生命周期
  • Spring Retry Spring 生态系统优雅的重试组件
  • 浏览器网页路径扫描器(脚本)
  • SQL优化:SQL模拟Split二维数组
  • Linux 基础开发工具
  • django-redis 使用类实现和使用
  • React(面试)
  • JUC之异步编程理论总结
  • 实现基于数据库 flag 状态的消息消费控制
  • 【docker】P1 虚拟化与容器化
  • 全球协作无障碍:cpolar+Nextcloud实现跨国文件共享
  • 通过远程桌面横向移动(破解凭证)