[动态规划] 以“跳石板”问题为例 [python]

题目描述:对于当前所处编号为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())


  • 2
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值