《算法零基础100讲》(第28讲) 递推问题

Posted 英雄哪里出来

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了《算法零基础100讲》(第28讲) 递推问题相关的知识,希望对你有一定的参考价值。

零、写在前面

  这是《算法零基础100讲》 专栏打卡学习的第二十八天了。
  有不少同学已经不甘心只刷题了,「 解题报告 」 也已经陆续安排上了。每天都会有五六篇高质量的 「 解题报告 」 被我 「 加精 」。如果觉得自己有能力的,也可以来 「 万人千题 」 社区发布你的 「 解题报告 」。千万级流量,你我共同拥有,当然,不忘初心才是最重要滴。

一、概念定义

  递推 和 数列关系紧密,一般就是由前几项的值经过一些运算,得到当前项的值。

二、题目描述

  长度为 n ( 1 ≤ n < 40 ) n(1 \\le n \\lt 40) n(1n<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 n1 个字符可以是任意字符;而如果第 n n n 个结尾的字符是'M',那么第 n − 1 n-1 n1 个字符只能是是'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[n1][0]+f[n1][1]+f[n1][2]f[n][1]=f[n1][0]+f[n1][1]+f[n1][2]f[n][2]=f[n1][0]+f[n1][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=02f[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=02f[n1][i]f[n][1]=i=02f[n1][i]f[n][2]=i=02f[n2][i]+i=02f[n2][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=02f[n][i]=2(i=02f[n1][i]+i=02f[n2][i]) g [ n ] = ∑ i = 0 2 f [ n ] [ i ] g[n] = \\sum_{i=0}^{2} f[n][i] g[n]=i=02f[n][i] 原式化解为 g [ n ] = 2 ∗ ( g [ n − 1 ] + g [ n − 2 ] ) g[n] = 2 *(g[n-1] + g[n-2]) g[n]=2(g[n1]+g[n2]) 计算首项 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];
}

五、推荐专栏

🧡《C语言入门100例》🧡

超级楼梯问题

六、习题练习

序号题目链接难度
1斐波那契数列★☆☆☆☆
2太波纳奇数列★☆☆☆☆
3帕斯卡三角形 I★☆☆☆☆
4帕斯卡三角形 II★☆☆☆☆
5爬楼梯★☆☆☆☆
6约瑟夫环★☆☆☆☆
7字符串转化后的各位数字之和★★☆☆☆
👇🏻 关注公众号 观看 精彩学习视频👇🏻

以上是关于《算法零基础100讲》(第28讲) 递推问题的主要内容,如果未能解决你的问题,请参考以下文章

《算法零基础100讲》(第61讲) 前缀和 二维前缀和

《算法零基础100讲》(第52讲) 区间问题 区间定义

《算法零基础100讲》(第3讲) 矩阵

《算法零基础100讲》(第26讲) 字符串算法 - 回文串

《算法零基础100讲》(第53讲) 区间问题 区间的并集和交集

《算法零基础100讲》(第25讲) 字符串算法 - 字符串反转