动态规划(一)| 豆包MarsCode AI刷题

75 阅读3分钟

你好

朋友们好!今天我们一起来探讨动态规划!这里主要是探讨线性的动态规划。根据我的总结,我发现,动态规划主要是三个要素:

  1. 懂得建立dp数组,一维或者二维来表示出题目的信息
  2. 理解题目的更新过程,建立状态转移方程
  3. 对于一些特别的地方要做出定义,比如数组开头之类的。

题目示例

生物学家小 R 正在研究一种特殊的兔子品种的繁殖模式。这种兔子的繁殖遵循以下规律:

  1. 每对成年兔子每个月会生育一对新的小兔子(一雌一雄)。
  2. 新生的小兔子需要一个月成长,到第二个月才能开始繁殖。
  3. 兔子永远不会死亡。

小 R 从一对新生的小兔子开始观察。他想知道在第 A 个月末,总共会有多少对兔子。 请你帮助小 R 编写一个程序,计算在给定的月份 A 时,兔子群体的总对数。 注意:

  • 初始时有 1 对新生小兔子。
  • 第 1 个月末有 1 对兔子:原来那对变成了成年兔子,并开始繁殖。
  • 第 2 个月末有 2 对兔子:原来那 1 对成年兔子,繁殖了 1 对新生的小兔子。
  • 从第 3 个月开始,兔子群体会按照上述规律增长。

题目分析

首先,我们要求的是兔子的对数,只有一个信息点,看来我们得dp数组是一维的,但大小呢,注意代码语言是从0开始编号的,那么我们要求第n个月份,数组长度就是n+1啦!

现在我们只需要找到转移逻辑,找到每个月到下一个月是如何迭代的就可以让代码模拟繁殖过程直到我们想要求得第n个月。兔子群体的总对数可以理解为:原有的兔子总数+成年的兔子繁殖的新兔子宝宝。那么原有的兔子总数当然是跟上个月末的数量一致,那么繁殖的兔子宝宝呢,由于新生的小兔子需要一个月成长,到第二个月才能开始繁殖,所以我们可以找到再上一个月的兔子总数,彼时的兔子对于当前月份来讲都是成年的繁殖新宝宝兔子。

现在我们来找到特别的初始状态,第0个月为0,第1个月为1,第二个月为2。

如此我们便建立了动态规划逻辑,只需要使用循环,不断更迭再取想要直到月份的数字,即是我们所求的答案了。

题目解答

def solution(A):
    if A <= 2:
        return A
    pairs = [0] * (A + 1)
    pairs[1], pairs[2] = 1, 2
    for i in range(3, A + 1):
        pairs[i] = pairs[i - 1] + pairs[i - 2]
    return pairs[A]