給定兩個正數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
操作;
# @time :2018/08/23
# @author :liuyinxing
class
solution:
defsolve
(self, m, n):
if m == n: return
0if abs(m-n) == 1: return
1if 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))
宣告:總結學習,有問題可以批評指正,大神可以略過哦。 演算法題 數字遊戲
小易邀請你玩乙個數字遊戲,小易給你一系列的整數。你們倆使用這些整數玩遊戲。每次小易會任意說乙個數字出來,然後你需要從這一系列數字中選取一部分出來讓它們的和等於小易所說的數字。例如 如果是你有的一系列數,小易說的數字是11.你可以得到方案2 2 7 11.如果頑皮的小易想坑你,他說的數字是6,那麼你沒...
演算法題 數字dp 計數問題(Python
給定兩個整數 a 和 b,求 a 和 b 之間的所有數字中0 9的出現次數。例如,a 1024,b 1032,則 a 和 b 之間共有9個數如下 1024 1025 1026 1027 1028 1029 1030 1031 1032 其中 0 出現10次,1 出現10次,2 出現7次,3 出現3次...
演算法題 Nim遊戲(Python)
給定n堆石子,兩位玩家輪流操作,每次操作可以從任意一堆石子中拿走任意數量的石子 可以拿完,但不能不拿 最後無法進行操作的人視為失敗。問如果兩人都採用最優策略,先手是否必勝。輸入格式 第一行包含整數n。第二行包含n個數字,其中第 i 個數字表示第 i 堆石子的數量。輸出格式 如果先手方必勝,則輸出 y...