《算法零基础100讲》(第28讲) 递推问题
Posted 英雄哪里出来
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了《算法零基础100讲》(第28讲) 递推问题相关的知识,希望对你有一定的参考价值。
零、写在前面
这是《算法零基础100讲》 专栏打卡学习的第二十八天了。
有不少同学已经不甘心只刷题了,「 解题报告 」 也已经陆续安排上了。每天都会有五六篇高质量的 「 解题报告 」 被我 「 加精 」。如果觉得自己有能力的,也可以来 「 万人千题 」 社区发布你的 「 解题报告 」。千万级流量,你我共同拥有,当然,不忘初心才是最重要滴。
一、概念定义
递推 和 数列关系紧密,一般就是由前几项的值经过一些运算,得到当前项的值。
二、题目描述
长度为 n ( 1 ≤ n < 40 ) n(1 \\le n \\lt 40) n(1≤n<40) 的只由
'A'
、'C'
、'M'
三种字符组成的字符串(可以只有其中一种或两种字符,但绝对不能有其他字符)且禁止出现M
相邻的情况,问这样的串有多少种?
三、算法详解
考虑长度为
n
n
n,且以'A'
结尾的串有
f
[
n
]
[
0
]
f[n][0]
f[n][0] 种、以'C'
结尾的串有
f
[
n
]
[
1
]
f[n][1]
f[n][1] 种、以'M'
结尾的串有
f
[
n
]
[
2
]
f[n][2]
f[n][2] 种,那么答案就是
∑
i
=
0
2
f
[
n
]
[
i
]
\\sum_{i=0}^{2} f[n][i]
∑i=02f[n][i]。
那么,我们来想一下怎么进行递推。
如果第
n
n
n 个结尾的字符是'A'
或者'C'
,那么显然, 第
n
−
1
n-1
n−1 个字符可以是任意字符;而如果第
n
n
n 个结尾的字符是'M'
,那么第
n
−
1
n-1
n−1 个字符只能是是'A'
或者'C'
。所以可以得到递推公式如下:
f
[
n
]
[
0
]
=
f
[
n
−
1
]
[
0
]
+
f
[
n
−
1
]
[
1
]
+
f
[
n
−
1
]
[
2
]
f
[
n
]
[
1
]
=
f
[
n
−
1
]
[
0
]
+
f
[
n
−
1
]
[
1
]
+
f
[
n
−
1
]
[
2
]
f
[
n
]
[
2
]
=
f
[
n
−
1
]
[
0
]
+
f
[
n
−
1
]
[
1
]
f[n][0] = f[n-1][0] + f[n-1][1] + f[n-1][2] \\\\ f[n][1] = f[n-1][0] + f[n-1][1] + f[n-1][2] \\\\ f[n][2] = f[n-1][0] + f[n-1][1]
f[n][0]=f[n−1][0]+f[n−1][1]+f[n−1][2]f[n][1]=f[n−1][0]+f[n−1][1]+f[n−1][2]f[n][2]=f[n−1][0]+f[n−1][1]
到这一步,我们就可以利用程序求解了,但是,还可以化解,由于
∑
i
=
0
2
f
[
n
]
[
i
]
=
f
[
n
]
[
0
]
+
f
[
n
]
[
1
]
+
f
[
n
]
[
2
]
\\sum_{i=0}^{2} f[n][i] = f[n][0] + f[n][1] + f[n][2]
i=0∑2f[n][i]=f[n][0]+f[n][1]+f[n][2] 于是,可以得出:
f
[
n
]
[
0
]
=
∑
i
=
0
2
f
[
n
−
1
]
[
i
]
f
[
n
]
[
1
]
=
∑
i
=
0
2
f
[
n
−
1
]
[
i
]
f
[
n
]
[
2
]
=
∑
i
=
0
2
f
[
n
−
2
]
[
i
]
+
∑
i
=
0
2
f
[
n
−
2
]
[
i
]
f[n][0] = \\sum_{i=0}^{2} f[n-1][i] \\\\ f[n][1] = \\sum_{i=0}^{2} f[n-1][i] \\\\ f[n][2] = \\sum_{i=0}^{2} f[n-2][i] + \\sum_{i=0}^{2} f[n-2][i]
f[n][0]=i=0∑2f[n−1][i]f[n][1]=i=0∑2f[n−1][i]f[n][2]=i=0∑2f[n−2][i]+i=0∑2f[n−2][i] 从而得到:
∑
i
=
0
2
f
[
n
]
[
i
]
=
2
∗
(
∑
i
=
0
2
f
[
n
−
1
]
[
i
]
+
∑
i
=
0
2
f
[
n
−
2
]
[
i
]
)
\\sum_{i=0}^{2} f[n][i] = 2 * (\\sum_{i=0}^{2} f[n-1][i] + \\sum_{i=0}^{2} f[n-2][i])
i=0∑2f[n][i]=2∗(i=0∑2f[n−1][i]+i=0∑2f[n−2][i]) 令
g
[
n
]
=
∑
i
=
0
2
f
[
n
]
[
i
]
g[n] = \\sum_{i=0}^{2} f[n][i]
g[n]=i=0∑2f[n][i] 原式化解为
g
[
n
]
=
2
∗
(
g
[
n
−
1
]
+
g
[
n
−
2
]
)
g[n] = 2 *(g[n-1] + g[n-2])
g[n]=2∗(g[n−1]+g[n−2]) 计算首项
g
[
1
]
=
3
,
g
[
2
]
=
8
g[1] = 3, g[2] = 8
g[1]=3,g[2]=8,递推求解。
四、源码剖析
long long getACM(int n) {
long long g[40];
g[1] = 3, g[2] = 8;
for(i = 3; i <= n; i++) {
g[i] = 2 * (g[i-1] + g[i-2]);
}
return g[n];
}
五、推荐专栏
六、习题练习
序号 | 题目链接 | 难度 |
---|---|---|
1 | 斐波那契数列 | ★☆☆☆☆ |
2 | 太波纳奇数列 | ★☆☆☆☆ |
3 | 帕斯卡三角形 I | ★☆☆☆☆ |
4 | 帕斯卡三角形 II | ★☆☆☆☆ |
5 | 爬楼梯 | ★☆☆☆☆ |
6 | 约瑟夫环 | ★☆☆☆☆ |
7 | 字符串转化后的各位数字之和 | ★★☆☆☆ |
以上是关于《算法零基础100讲》(第28讲) 递推问题的主要内容,如果未能解决你的问题,请参考以下文章