📌  相关文章
📜  通过将每一步乘以 2、3、4 或 5,从 1 达到 N 的最小步数(1)

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

通过将每一步乘以 2、3、4 或 5,从 1 达到 N 的最小步数

问题描述

给定一个正整数 N,每次可以将当前数乘以 2、3、4 或 5,求从 1 开始最少需要多少步才能得到 N。

思路分析

这是一道比较典型的动态规划问题。我们可以使用一个数组 $dp$,数组中的每个元素 $dp[i]$ 表示从 1 开始到达 $i$,最小需要多少步。那么我们就需要从 $dp[1]$ 到 $dp[N]$ 开始填表格。

当我们计算 $dp[i]$ 的值时,可以通过以下四个状态转移方程得到:

$$dp[i]=\min\begin{cases}dp[\frac{i}{2}]+1\dp[\frac{i}{3}]+1\dp[\frac{i}{4}]+1\dp[\frac{i}{5}]+1\end{cases}$$

这里需要注意,每次计算 $dp[i]$ 时,我们需要保证 $\frac{i}{2}$、$\frac{i}{3}$、$\frac{i}{4}$、$\frac{i}{5}$ 都为整数。这个条件在程序实现时需要格外注意。

最后 $dp[N]$ 的值即为所求解。

代码实现
def min_steps_to_N(N: int) -> int:
    dp = [0] * (N + 1)

    for i in range(2, N + 1):
        dp[i] = dp[i // 2] + 1
        if i % 3 == 0:
            dp[i] = min(dp[i], dp[i // 3] + 1)
        if i % 4 == 0:
            dp[i] = min(dp[i], dp[i // 4] + 1)
        if i % 5 == 0:
            dp[i] = min(dp[i], dp[i // 5] + 1)

    return dp[N]
性能分析

由上述算法实现可以看出,该算法的时间复杂度为 $O(N \log N)$,空间复杂度为 $O(N)$。在处理较小的数据时,该算法具有较好的实用性。