问题分析:
给定两个正数 m
,n
(0<=m<=n
),现在求,从 m
开始,只能 加1
,或者乘以2
最后得到n
的最小操作次数
。
问题分析:
很显然是一个动态规划题目,首先考虑一个 m=1
的情况,不难得出 dp方程
:
dp[1] = 0
n为偶数: dp[n] = min(dp[n-1]+1, dp[n/2]+1)
n为奇数: dp[n] = min(dp[n-1]+1, dp[(n-1)/2]+2) # dp[(n-1)/2]+2 先乘再加
dp[n]
表示从 1
到 n
最小操作次数。
那么,现在把 m
的值推广一下,其实思路和上面完全一样,但要注意两点:
(1)第一个值要初始化为 0
;
(2)在回头判断 dp[n/2]
, dp[(n-1)/2]
时,要注意数组算法越界,如果越界了很显然,只能做 +1
操作;
Python3实现:
# @Time :2018/08/23
# @Author :LiuYinxing
class Solution:
def Solve(self, m, n):
if m == n: return 0
if abs(m-n) == 1: return 1
if n < m: m, n = n, m # 保持 m 是小的
dp = [0] * (n-m+1)
dp[1] = 1
for i in range(2, (n-m+1)):
if (i + m) % 2 == 0: # 偶数的情况
if (i + m) // 2 < m: # 判断是否出界
dp[i] = dp[i - 1] + 1
else:
dp[i] = min(dp[i - 1] + 1, dp[(i+m) // 2 - m] + 1)
else: # 奇数的情况
if (i + m - 1) // 2 < m:
dp[i] = dp[i - 1] + 1
else:
dp[i] = min(dp[i - 1] + 1, dp[(i + m - 1) // 2 - m] + 2) # dp[(n-1)/2]+2
print(dp)
return dp[-1]
if __name__ == '__main__':
solu = Solution()
print(solu.Solve(7, 9))
声明:总结学习,有问题可以批评指正,大神可以略过哦。