8.1递推关系的运用

本文详细探讨了递推关系在解决各种问题中的应用,如兔子和斐波那契数列、汉诺塔、连续串的计数、编码字的枚举以及乘积中加括号的方法数。通过转化思想,将复杂问题转化为简单的递推公式,并介绍了动态规划的基本思路,为解决实际问题提供了有效的方法。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

8.1.1 兔子和斐波拉契数列

思路:用fnfn表示n个月后的兔子对数。

转化思想:当n3的时候,fnfn等于前一个月的对数fn1fn−1加上新出生的兔子(fn2fn−2)。
fnfn= fn1fn−1+ fn2fn−2

8.1.2 汉诺塔

思路:用fnfn表示解n个盘子的汉诺塔问题所需要的移动次数。

转化思想:我们可以先用fn1fn−1次移动将上边的n1n−1个盘子移到柱c,在这些移动中保留最大的盘子不动。然后我们用一次移动将最大的盘子移到第二根柱子上面。我们可以再使用fn1fn−1次移动将柱c上的n-1个盘子移动到柱b,把它们放在最大的盘子的上面。
fn1fn−1+ fn2fn−2
这里写图片描述

8.1.3 连续串

找出不含2个连续0的n位二进制串的个数。

思路:用fnfn表示不含2个连续0的n位二进制串的个数。
由于二进制串的最后一位必须是0和1中的一个,所以当最后一位为1的时候,转换成了不含2个连续0的n1n−1位二进制串的个数,如果最后一位是0,那么倒数第二位必须是1,于是转换成了不含2个连续0的n2n−2位二进制串的个数。
fn1fn−1+ fn2fn−2

8.1.4 编码字的枚举

背景知识:计算机把一个十进制数字串作为一个编码字,如果它包含偶数个零,那么他就是有效的,找出nn位有效编码字的个数。

思路:用fn表示nn位编码字的个数。

转化思想:当n=1的时候,容易知道有9个;
我们考虑在下面两种情况:
(1)在一个n1n−1位的有效数字串的后面加一个非零的数字就构成了n位有效的数字串,因此这种方法一共构造了9fn19fn−1种;
(2)在一个n1n−1位的无效数字串的后面加一个零就构成了n位有效的数字串,因此这种方法一共构造了10n1fn110n−1−fn−1种;
结合上面两种情况,我们知道一共有10n1fn1+9fn110n−1−fn−1+9fn−1=10n1+8fn110n−1+8fn−1

8.1.4 乘积中加括号规定乘法的次数的方式数

背景知识:求关于CnCn的表达式,其中CnCn是通过对n+1n+1个数x1x1x2x2x3x3xnxn的乘积中加括号来规定乘法次数的方法数。

解题思路:

我们可以发现,无论我们怎样在其中加括号,用会有一个“”留在所有括号的外面,即执行最后一次乘法的运算。这个最后的运算符出现在n+1n+1个数中的两个数字之间,比如说xkxkxk+1xk+1之间。当最后的运算符出现在xkxkxk+1xk+1之间时,存在
CkCkCnk1Cn−k−1种方法插入括号来决定n+1个数被乘的次数,因为有CkCk种方法在x1x1x2x2x3x3xkxk中插入括号来决定这k+1个数字的乘法次序,所以有Cnk1Cn−k−1种方法在乘积xk+1xk+1xk+2xk+2xk+3xk+3xnxn来插入括号来决定这n-k个数字的乘法次序
初始条件是C0C0=1,C1C1=1;

8.2 动态规划

### 序关系计数问题 对于序关系计数问题,这类问题是组合数学中的一个重要分支。具体来说,当面对一组元素并试图确定这些元素之间的特定排列数量时,就涉及到此类问题。例如,在给定一定条件的情况下计算满足条件的同序列的数量。 #### 动态规划应用于序关系计数 建立递归关系是解决问题的关键之一。通过定义合适的状态转移方程来描述如何从前一步骤的结果推导出下一步骤的结果[^1]。这通常意味着要找出当前状态与其他可能前驱状态间的关系,并利用这种关系构建解决方案。识别最优子结构同样重要;这意味着理解较小规模的问题是如何组成更大规模问题的基础部分。最后,应用备忘录机制能够有效提高效率,防止重复计算相同的子问题。 ```python def count_sequences(n, m): dp = [[0]*(m+1) for _ in range(n+1)] # Base case initialization for i in range(m+1): dp[0][i] = 1 for i in range(1, n+1): for j in range(i, m+1): dp[i][j] = sum(dp[i-1][:j]) return dp[n][m] print(count_sequences(3, 5)) ``` 此代码片段展示了如何使用动态规划解决简单的序关系计数问题——即在一个范围内选取若干个重复整数组成有序列表的方法总数。 ### 矩阵链乘法 矩阵链乘法是指多个矩阵连续相乘的过程。由于矩阵乘法具有结合律而具备交换律,所以同的加括号方式会影响最终所需的总乘法次数。目标是在所有合法的加括号方案中寻找使总的标量乘法操作最少的一种。 #### 使用动态规划求解矩阵链乘法 为了最小化所需执行的操作数目,可以通过引入二维表格`dp[i][j]`表示从第`i`到第`j`个矩阵的最佳(最低成本)乘积路径来进行优化。这里的核心在于迭代地填充这个表,直到获得整个链条的最佳分割点为止。每次更新都基于之前已知的信息,从而逐步建立起全局最优解。 ```python import sys def matrix_chain_order(p): n = len(p)-1 dp = [[sys.maxsize]*n for _ in range(n)] # 初始化单个矩阵的情况 for i in range(n): dp[i][i]=0 for l in range(2,n+1): for i in range(n-l+1): j=i+l-1 for k in range(i,j): q=dp[i][k]+dp[k+1][j]+p[i]*p[k+1]*p[j+1] if q<dp[i][j]: dp[i][j]=q return dp[0][-1] dimensions=[40,20,30,10,30] result=matrix_chain_order(dimensions) print(f"The minimum number of multiplications is {result}") ``` 这段Python程序实现了针对给定尺寸向量`p`所代表的一系列矩形矩阵间的最佳乘法规则查找过程。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值