题目描述:对于当前所处编号为K的石板,单次只能向前跳K的一个约数步(除了1和它本身),问:若当前所处编号为N,想跳到M,最少跳几次?
思路:动态规划思想。创建一个list 存放steps,steps[i]表示到达i号石板所需的最小步数。另一个list存放每一点的所有因数列表。
恭喜你通过本题
运行时间:770ms
占用内存:23008k
import itertools #用于初始化 dp数组
def foo():
dp=[x for x in itertools.repeat(-1,M*2)] #用于盛放每个点到达M点的最小跳跃数
T=[[] for x in itertools.repeat(None,M)] #用于盛放每个点的所有因数
dp[M]=0
i=(M-1)//2 #从最大因数往下循环。此求因数的办法可以省掉不是因数的判断,避免重复计算
while i > 1: #因数不能为1
j=i*2 #从因数i的最小可能合数往上循环
while j<M:
T[j].append(i)
j+=1
i-=1
#求完因数后,更新dp
i=M-1 #从M-1点往N点遍历更新dp
while i>=N:
for k in T[i]:
v=dp[i+k]+1 #表示 在i点的每一种跳法,所对应的到M点的最小跳跃数。取最小值。
if v==0: #意味着i+k点不可达M,换下一种
continue
if dp[i]==-1:
dp[i]=v
elif v<dp[i]:
dp[i]=v
i-=1
return dp[N]
N,M=[int(x) for x in input().split()]
print(foo())