📌  相关文章
📜  计数通过遵循某些规则将N减少到1所需的步数(1)

📅  最后修改于: 2023-12-03 15:27:57.729000             🧑  作者: Mango

题目介绍

给定一个正整数N,计数通过遵循以下规则将N减少到1所需的步数:

  • 如果N是偶数,则将其除以2。
  • 如果N是奇数,则减去1或加上1(可以选择)。
解决方案

很明显,这是一道动态规划问题。我们可以想象,从1开始,一步步往上增加数字,每一个数字都可以根据前面的数字得到。

因为只有两种方式可以达到当前数字,所以我们需要比较两种方式得到的结果,选择最小的那个。

如何表示子问题?我们可以使用一个数组,将每一个数字的步数记录下来。

代码如下:

def steps_to_one(n):
    # 初始化数组,默认为0
    dp = [0] * (n+1)
    # 从2开始计算,因为1不需要计算
    for i in range(2, n+1):
        # 默认情况下,当前数字减1会比加1好
        dp[i] = dp[i-1] + 1
        # 如果当前数字可以被2整除,那么除以2肯定更好
        if i % 2 == 0:
            dp[i] = min(dp[i], dp[i//2] + 1)
    # 返回n的步数
    return dp[n]

这段代码的时间复杂度是O(n),因为我们需要计算每一个数字的步数。

总结

本题是一道经典的动态规划问题,适合初学者练习。我们需要将问题分解成子问题,并且使用一个数组来记录每一个数字的步数。最后根据子问题的结果,得到最终的答案。

完整代码如下:

def steps_to_one(n):
    # 初始化数组,默认为0
    dp = [0] * (n+1)
    # 从2开始计算,因为1不需要计算
    for i in range(2, n+1):
        # 默认情况下,当前数字减1会比加1好
        dp[i] = dp[i-1] + 1
        # 如果当前数字可以被2整除,那么除以2肯定更好
        if i % 2 == 0:
            dp[i] = min(dp[i], dp[i//2] + 1)
    # 返回n的步数
    return dp[n]