《具体数学》学习笔记: 1.递归问题

《具体数学》学习笔记: 1.递归问题

序言:
本系列将记录《具体数学》中学习的重要内容。第一章,递归问题中探讨了三个范例。

1.1 汉诺塔(The Tower of Hanoi)
问题描述:给定三个桩柱,标记为 a , b , c a, b, c a,b,c。另有 n n n 个圆盘,这些圆盘以大小递减的方式套在桩柱 a a a 上。 目标使得要将全部圆盘移动到另一根桩柱 b b b 上,每次只能移动一个圆盘,且较大的圆盘在移动过程中不能放置在较小的圆盘上面。
汉诺塔示意

递归思路:对于 n n n 个圆盘,我们首先要将 n − 1 n - 1 n1 个圆盘移动到辅助桩柱 c c c 上,然后将最后一个圆盘从 a a a 移动到桩柱 b b b 上,再把 c c c 上的 n − 1 n - 1 n1 个桩柱移动到 b b b 上。

我们用 T n T_n Tn 表示移动 n n n 个圆盘的总花费 c o s t cost cost, 则
T n = 2 T n − 1 + 1 T 0 = 0 , T 1 = 1 T_n = 2T_{n-1} + 1\\ T_0 = 0, T_1 = 1 Tn=2Tn1+1T0=0,T1=1

利用数学归纳法或者配置等比数列,可以得到
T n = 2 n − 1 , n ≥ 0 T_n = 2^n - 1, \quad n\ge0 Tn=2n1,n0

  • C++实现
void hanio(int n, char a, char b, char c) {
    if (n == 1) cout << a << " -> " << b << endl;
    else {
        hanio(n - 1, a, c, b);
        cout << a << " -> " << b << endl;
        hanio(n - 1, c, b, a);
    }
}
int main() {
    hanio(5, 'a', 'b', 'c');
    return 0;
}

1.2 平面上的直线(Lines in The Plane)
问题描述:平面上 n n n 条直线所界定的区域的最大个数 L n L_n Ln 是多少?
直线
递归思路:从前3项来看,似乎 L n = 2 n L_n=2^n Ln=2n, 但是显然 L 3 = 7 L_3=7 L3=7是不符合猜想的。换一种思路, L n L_{n} Ln 是在 L n − 1 L_{n - 1} Ln1 的基础上增加一条直线,而新的直线能与之前 n − 1 n - 1 n1条直线形成 n − 1 n - 1 n1 个交点,并形成 n − 1 + 1 = n n - 1 + 1 = n n1+1=n 个新的区域,即
L n = L n − 1 + n L 0 = 1 , L 1 = 2 L_n = L_{n-1} + n\\ L_0 = 1, L_1 = 2 Ln=Ln1+nL0=1,L1=2
可以解出 L n = ( L 0 + ∑ k = 1 n k ) = 1 + n ( n + 1 ) 2 L_n = (L_0 + \sum_{k = 1}^{n}{k}) = 1 + \frac{n(n+1)}{2} Ln=(L0+k=1nk)=1+2n(n+1).

另外,本书中还提到一种扩展形式:将直线改成折线,具体如下示
折线1
我们可以把折线与两条直线相比较,如果用折线代替两条直线,我们会“损失” 2 个区域(本来是4个, 现在只有2个)
折线2
因此这种情况下, Z n = L 2 n − 2 n = 2 n 2 − n + 1 Z_n = L_{2n} - 2n = 2n^2 - n + 1 Zn=L2n2n=2n2n+1.

1.3 约瑟夫问题(The Josephus Problem)
问题描述: n n n 个人围成一个圆圈,分别从 1 标记到 n n n。从1号位开始,每隔 1 个人删去 1 个人,直到圆圈中只剩下一个人,例如 n = 10 n = 10 n=10 的情形:消去的顺序是2, 4, 6, 8, 10, 3, 7, 1, 9, 于是 5 幸存下来。我们需要求解幸存者的号码 J ( n ) J(n) J(n).
环
递归式(分析比较复杂, 这里直接记住):
J ( 1 ) = 1 ; J ( 2 n ) = 2 J ( n ) − 1 , n ≥ 1 ; J ( 2 n + 1 ) = 2 J ( n ) + 1 , n ≥ 1 ; \begin{aligned} &amp;J(1) = 1;\\ &amp;J(2n) = 2J(n) - 1, &amp;\quad n \ge 1;\\ &amp;J(2n + 1) = 2J(n) + 1, &amp;\quad n \ge 1;\\ \end{aligned} J(1)=1;J(2n)=2J(n)1,J(2n+1)=2J(n)+1,n1;n1;
解为:
J ( ( b m b m − 1 . . . b 1 b 0 ) 2 ) = ( b m − 1 . . . b 0 b 1 b m ) 2 J((b_mb_{m-1}...b_1b_0)_2) = (b_{m-1}...b_0b_1b_m)_2 J((bmbm1...b1b0)2)=(bm1...b0b1bm)2
即,在 n n n 的二进制下,向左循环移动1位便可以得到 J ( n ) J(n) J(n).

  • 拓展

对于形如
f ( j ) = α j , 1 ≤ j &lt; d ; f ( d n + j ) = c f ( n ) + β j , 0 ≤ j &lt; d ,   n ≥ 1 ; \begin{aligned} &amp;f(j) = \alpha_j, \quad &amp;1 \le j &lt; d;\\ &amp;f(dn + j) = cf(n) + \beta_j, \quad &amp;0 \le j &lt; d,\ n \ge1; \end{aligned} f(j)=αj,f(dn+j)=cf(n)+βj,1j<d;0j<d, n1;
的递归式,他有变动基数的解
f ( ( b m b m − 1 . . . b 1 b 0 ) d ) = ( α b m β b m − 1 β b m − 2 . . . β b 1 β b 0 ) c f((b_mb_{m-1}...b_1b_0)_d) = (\alpha_{b_m}\beta_{b_{m-1}}\beta_{b_{m-2}}...\beta_{b_{1}}\beta_{b_{0}})_c f((bmbm1...b1b0)d)=(αbmβbm1βbm2...βb1βb0)c
即,我们需要将 d d d 进制下的 n n n 按照相应的变换规则,转换成 c c c 进制,便是所求解。其中,首项遵循边界式 ( α ) (\alpha) (α),其余项遵循递归式 ( β ) (\beta) (β)
例如,给定递归式
f ( 1 ) = 34 ; f ( 2 ) = 5 ; f ( 3 n ) = 10 f ( n ) + 76 , n ≥ 1 ; f ( 3 n + 1 ) = 10 f ( n ) − 2 , n ≥ 1 ; f ( 3 n + 2 ) = 10 f ( n ) + 8 , n ≥ 1 ; \begin{aligned} f(1) &amp;= 34;\\ f(2) &amp;= 5;\\ f(3n) &amp;= 10f(n) + 76, &amp;\quad n \ge 1;\\ f(3n + 1) &amp;= 10f(n) - 2, &amp;\quad n \ge 1;\\ f(3n + 2) &amp;= 10f(n) + 8, &amp;\quad n \ge 1; \end{aligned} f(1)f(2)f(3n)f(3n+1)f(3n+2)=34;=5;=10f(n)+76,=10f(n)2,=10f(n)+8,n1;n1;n1;
若求解 f ( 19 ) f(19) f(19),根据上述理论,我们需要将 19 的 3 进制 ( 201 ) 3 (2 0 1)_3 (201)3转换成 10 进制:

  1. 2 → 5 2 \to 5 25
  2. 0 → 76 0 \to 76 076
  3. 1 → − 2 1 \to -2 12

因此, f ( 19 ) = ( 5    76   − 2 ) 10 = 1258 f(19) = (5\ \ 76\ -2)_{10} = 1258 f(19)=(5  76 2)10=1258.

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值